diff --git a/trytond/pyson.py b/trytond/pyson.py index bb29add38c..d1c5c1d163 100644 --- a/trytond/pyson.py +++ b/trytond/pyson.py @@ -6,7 +6,23 @@ except ImportError: import json import datetime from dateutil.relativedelta import relativedelta -from functools import reduce +from functools import reduce, wraps + + +def reduced_type(types): + types = types.copy() + for k, r in [(long, int), (str, basestring), (unicode, basestring)]: + if k in types: + types.remove(k) + types.add(r) + return types + + +def reduce_type(func): + @wraps(func) + def wrapper(*args, **kwargs): + return reduced_type(func(*args, **kwargs)) + return wrapper class PYSON(object): @@ -123,6 +139,7 @@ class Eval(PYSON): 'd': self._default, } + @reduce_type def types(self): if isinstance(self._default, PYSON): return self._default.types() @@ -225,11 +242,11 @@ class Equal(PYSON): if isinstance(statement1, PYSON): types1 = statement1.types() else: - types1 = set([type(statement1)]) + types1 = reduced_type(set([type(statement1)])) if isinstance(statement2, PYSON): types2 = statement2.types() else: - types2 = set([type(statement2)]) + types2 = reduced_type(set([type(statement2)])) assert types1 == types2, 'statements must have the same type' self._statement1 = statement1 self._statement2 = statement2 @@ -324,13 +341,13 @@ class If(PYSON): if isinstance(then_statement, PYSON): then_types = then_statement.types() else: - then_types = set([type(then_statement)]) + then_types = reduced_type(set([type(then_statement)])) if isinstance(else_statement, PYSON): - assert then_types == else_statement.types(), \ - 'then and else statements must be the same type' + else_types = else_statement.types() else: - assert then_types == set([type(else_statement)]), \ - 'then and else statements must be the same type' + else_types = reduced_type(set([type(else_statement)])) + assert then_types == else_types, \ + 'then and else statements must be the same type' self._condition = condition self._then_statement = then_statement self._else_statement = else_statement @@ -343,6 +360,7 @@ class If(PYSON): 'e': self._else_statement, } + @reduce_type def types(self): if isinstance(self._then_statement, PYSON): return self._then_statement.types() @@ -367,9 +385,9 @@ class Get(PYSON): assert isinstance(obj, dict), 'obj must be a dict' self._obj = obj if isinstance(key, PYSON): - assert key.types() == set([str, unicode]), 'key must be a string' + assert key.types() == set([basestring]), 'key must be a string' else: - assert type(key) in [str, unicode], 'key must be a string' + assert isinstance(key, basestring), 'key must be a string' self._key = key self._default = default @@ -381,6 +399,7 @@ class Get(PYSON): 'd': self._default, } + @reduce_type def types(self): if isinstance(self._default, PYSON): return self._default.types() @@ -397,20 +416,20 @@ class In(PYSON): def __init__(self, key, obj): super(In, self).__init__() if isinstance(key, PYSON): - assert key.types().issubset(set([str, unicode, int, long])), \ + assert key.types().issubset(set([basestring, int])), \ 'key must be a string or an integer or a long' else: - assert type(key) in [str, unicode, int, long], \ + assert isinstance(key, (basestring, int, long)), \ 'key must be a string or an integer or a long' if isinstance(obj, PYSON): assert obj.types().issubset(set([dict, list])), \ 'obj must be a dict or a list' if obj.types() == set([dict]): - assert type(key) in [str, unicode], 'key must be a string' + assert isinstance(key, basestring), 'key must be a string' else: - assert type(obj) in [dict, list] - if type(obj) == dict: - assert type(key) in [str, unicode], 'key must be a string' + assert isinstance(obj, (dict, list)) + if isinstance(obj, dict): + assert isinstance(key, basestring), 'key must be a string' self._key = key self._obj = obj @@ -487,7 +506,7 @@ class DateTime(Date): for i in (hour, minute, second, microsecond, delta_hours, delta_minutes, delta_seconds, delta_microseconds): if isinstance(i, PYSON): - assert i.types() == set([int, long, type(None)]), \ + assert i.types() == set([int, type(None)]), \ '%s must be an integer or None' % (i,) else: assert isinstance(i, (int, long, type(None))), \ @@ -542,10 +561,10 @@ class Len(PYSON): def __init__(self, value): super(Len, self).__init__() if isinstance(value, PYSON): - assert value.types().issubset(set([dict, list, str, unicode])), \ + assert value.types().issubset(set([dict, list, basestring])), \ 'value must be a dict or a list or a string' else: - assert type(value) in [dict, list, str, unicode], \ + assert isinstance(value, (dict, list, basestring)), \ 'value must be a dict or list or a string' self._value = value @@ -556,7 +575,7 @@ class Len(PYSON): } def types(self): - return set([int, long]) + return set([int]) @staticmethod def eval(dct, context): diff --git a/trytond/tests/test_pyson.py b/trytond/tests/test_pyson.py index 47300d52c4..de0e411921 100644 --- a/trytond/tests/test_pyson.py +++ b/trytond/tests/test_pyson.py @@ -12,34 +12,34 @@ class PYSONTestCase(unittest.TestCase): def test0010Eval(self): 'Test pyson.Eval' - self.assert_(pyson.Eval('test').pyson() == { + self.assertEqual(pyson.Eval('test').pyson(), { '__class__': 'Eval', 'v': 'test', 'd': '', }) - self.assert_(pyson.Eval('test', 'foo').pyson() == { + self.assertEqual(pyson.Eval('test', 'foo').pyson(), { '__class__': 'Eval', 'v': 'test', 'd': 'foo', }) - self.assert_(pyson.Eval('test', 'foo').types() == set([type('foo')])) - self.assert_(pyson.Eval('test', 1).types() == set([type(1)])) + self.assertEqual(pyson.Eval('test', 'foo').types(), set([basestring])) + self.assertEqual(pyson.Eval('test', 1).types(), set([int])) eval = pyson.PYSONEncoder().encode(pyson.Eval('test', 0)) - self.assert_(pyson.PYSONDecoder({'test': 1}).decode(eval) == 1) - self.assert_(pyson.PYSONDecoder().decode(eval) == 0) + self.assertEqual(pyson.PYSONDecoder({'test': 1}).decode(eval), 1) + self.assertEqual(pyson.PYSONDecoder().decode(eval), 0) def test0020Not(self): 'Test pyson.Not' - self.assert_(pyson.Not(True).pyson() == { + self.assertEqual(pyson.Not(True).pyson(), { '__class__': 'Not', 'v': True, }) self.assertRaises(AssertionError, pyson.Not, 'foo') - self.assert_(pyson.Not(True).types() == set([bool])) + self.assertEqual(pyson.Not(True).types(), set([bool])) eval = pyson.PYSONEncoder().encode(pyson.Not(True)) self.assertFalse(pyson.PYSONDecoder().decode(eval)) @@ -49,12 +49,12 @@ class PYSONTestCase(unittest.TestCase): def test0030Bool(self): 'Test pyson.Bool' - self.assert_(pyson.Bool('test').pyson() == { + self.assertEqual(pyson.Bool('test').pyson(), { '__class__': 'Bool', 'v': 'test', }) - self.assert_(pyson.Bool('test').types() == set([bool])) + self.assertEqual(pyson.Bool('test').types(), set([bool])) eval = pyson.PYSONEncoder().encode(pyson.Bool(True)) self.assertTrue(pyson.PYSONDecoder().decode(eval)) @@ -88,7 +88,7 @@ class PYSONTestCase(unittest.TestCase): def test0040And(self): 'Test pyson.And' - self.assert_(pyson.And(True, False).pyson() == { + self.assertEqual(pyson.And(True, False).pyson(), { '__class__': 'And', 's': [True, False], }) @@ -99,7 +99,7 @@ class PYSONTestCase(unittest.TestCase): self.assertRaises(AssertionError, pyson.And, True) self.assertRaises(AssertionError, pyson.And) - self.assert_(pyson.And(True, False).types() == set([bool])) + self.assertEqual(pyson.And(True, False).types(), set([bool])) eval = pyson.PYSONEncoder().encode(pyson.And(True, True)) self.assertTrue(pyson.PYSONDecoder().decode(eval)) @@ -130,7 +130,7 @@ class PYSONTestCase(unittest.TestCase): def test0050Or(self): 'Test pyson.Or' - self.assert_(pyson.Or(True, False).pyson() == { + self.assertEqual(pyson.Or(True, False).pyson(), { '__class__': 'Or', 's': [True, False], }) @@ -141,7 +141,7 @@ class PYSONTestCase(unittest.TestCase): self.assertRaises(AssertionError, pyson.Or, True) self.assertRaises(AssertionError, pyson.Or) - self.assert_(pyson.Or(True, False).types() == set([bool])) + self.assertEqual(pyson.Or(True, False).types(), set([bool])) eval = pyson.PYSONEncoder().encode(pyson.Or(True, True)) self.assertTrue(pyson.PYSONDecoder().decode(eval)) @@ -172,7 +172,7 @@ class PYSONTestCase(unittest.TestCase): def test0060Equal(self): 'Test pyson.Equal' - self.assert_(pyson.Equal('test', 'test').pyson() == { + self.assertEqual(pyson.Equal('test', 'test').pyson(), { '__class__': 'Equal', 's1': 'test', 's2': 'test', @@ -180,7 +180,7 @@ class PYSONTestCase(unittest.TestCase): self.assertRaises(AssertionError, pyson.Equal, 'test', True) - self.assert_(pyson.Equal('test', 'test').types() == set([bool])) + self.assertEqual(pyson.Equal('test', 'test').types(), set([bool])) eval = pyson.PYSONEncoder().encode(pyson.Equal('test', 'test')) self.assertTrue(pyson.PYSONDecoder().decode(eval)) @@ -190,7 +190,7 @@ class PYSONTestCase(unittest.TestCase): def test0070Greater(self): 'Test pyson.Greater' - self.assert_(pyson.Greater(1, 0).pyson() == { + self.assertEqual(pyson.Greater(1, 0).pyson(), { '__class__': 'Greater', 's1': 1, 's2': 0, @@ -201,7 +201,7 @@ class PYSONTestCase(unittest.TestCase): self.assertRaises(AssertionError, pyson.Greater, 1, 'test') self.assertRaises(AssertionError, pyson.Greater, 1, 0, 'test') - self.assert_(pyson.Greater(1, 0).types() == set([bool])) + self.assertEqual(pyson.Greater(1, 0).types(), set([bool])) eval = pyson.PYSONEncoder().encode(pyson.Greater(1, 0)) self.assertTrue(pyson.PYSONDecoder().decode(eval)) @@ -223,7 +223,7 @@ class PYSONTestCase(unittest.TestCase): def test0080Less(self): 'Test pyson.Less' - self.assert_(pyson.Less(0, 1).pyson() == { + self.assertEqual(pyson.Less(0, 1).pyson(), { '__class__': 'Less', 's1': 0, 's2': 1, @@ -234,7 +234,7 @@ class PYSONTestCase(unittest.TestCase): self.assertRaises(AssertionError, pyson.Less, 0, 'test') self.assertRaises(AssertionError, pyson.Less, 0, 1, 'test') - self.assert_(pyson.Less(0, 1).types() == set([bool])) + self.assertEqual(pyson.Less(0, 1).types(), set([bool])) eval = pyson.PYSONEncoder().encode(pyson.Less(0, 1)) self.assertTrue(pyson.PYSONDecoder().decode(eval)) @@ -256,7 +256,7 @@ class PYSONTestCase(unittest.TestCase): def test0090If(self): 'Test pyson.If' - self.assert_(pyson.If(True, 'foo', 'bar').pyson() == { + self.assertEqual(pyson.If(True, 'foo', 'bar').pyson(), { '__class__': 'If', 'c': True, 't': 'foo', @@ -267,18 +267,18 @@ class PYSONTestCase(unittest.TestCase): self.assertRaises(AssertionError, pyson.If, True, 'foo', False) self.assertEqual(pyson.If(True, 'foo', 'bar').types(), - set([type('foo')])) - self.assert_(pyson.If(True, False, True).types() == set([bool])) + set([basestring])) + self.assertEqual(pyson.If(True, False, True).types(), set([bool])) eval = pyson.PYSONEncoder().encode(pyson.If(True, 'foo', 'bar')) - self.assert_(pyson.PYSONDecoder().decode(eval) == 'foo') + self.assertEqual(pyson.PYSONDecoder().decode(eval), 'foo') eval = pyson.PYSONEncoder().encode(pyson.If(False, 'foo', 'bar')) - self.assert_(pyson.PYSONDecoder().decode(eval) == 'bar') + self.assertEqual(pyson.PYSONDecoder().decode(eval), 'bar') def test0100Get(self): 'Test pyson.Get' - self.assert_(pyson.Get({'foo': 'bar'}, 'foo', 'default').pyson() == { + self.assertEqual(pyson.Get({'foo': 'bar'}, 'foo', 'default').pyson(), { '__class__': 'Get', 'v': {'foo': 'bar'}, 'k': 'foo', @@ -288,24 +288,25 @@ class PYSONTestCase(unittest.TestCase): self.assertRaises(AssertionError, pyson.Get, 'test', 'foo', 'default') self.assertRaises(AssertionError, pyson.Get, {}, 1, 'default') - self.assert_(pyson.Get({}, 'foo', 'default').types() == set([str])) - self.assert_(pyson.Get({}, 'foo', True).types() == set([bool])) + self.assertEqual(pyson.Get({}, 'foo', 'default').types(), + set([basestring])) + self.assertEqual(pyson.Get({}, 'foo', True).types(), set([bool])) eval = pyson.PYSONEncoder().encode(pyson.Get( {'foo': 'bar'}, 'foo', 'default')) - self.assert_(pyson.PYSONDecoder().decode(eval) == 'bar') + self.assertEqual(pyson.PYSONDecoder().decode(eval), 'bar') eval = pyson.PYSONEncoder().encode(pyson.Get( {'foo': 'bar'}, 'test', 'default')) - self.assert_(pyson.PYSONDecoder().decode(eval) == 'default') + self.assertEqual(pyson.PYSONDecoder().decode(eval), 'default') eval = pyson.PYSONEncoder().encode(pyson.Get( {}, 'foo', 'default')) - self.assert_(pyson.PYSONDecoder().decode(eval) == 'default') + self.assertEqual(pyson.PYSONDecoder().decode(eval), 'default') def test0110In(self): 'Test pyson.In' - self.assert_(pyson.In('foo', {'foo': 'bar'}).pyson() == { + self.assertEqual(pyson.In('foo', {'foo': 'bar'}).pyson(), { '__class__': 'In', 'k': 'foo', 'v': {'foo': 'bar'}, @@ -314,7 +315,7 @@ class PYSONTestCase(unittest.TestCase): self.assertRaises(AssertionError, pyson.In, object(), {}) self.assertRaises(AssertionError, pyson.In, 'test', 'foo') - self.assert_(pyson.In('foo', {}).types() == set([bool])) + self.assertEqual(pyson.In('foo', {}).types(), set([bool])) eval = pyson.PYSONEncoder().encode(pyson.In('foo', {'foo': 'bar'})) self.assertTrue(pyson.PYSONDecoder().decode(eval)) @@ -348,7 +349,7 @@ class PYSONTestCase(unittest.TestCase): def test0120Date(self): 'Test pyson.Date' - self.assert_(pyson.Date(2010, 1, 12, -1, 12, -7).pyson() == { + self.assertEqual(pyson.Date(2010, 1, 12, -1, 12, -7).pyson(), { '__class__': 'Date', 'y': 2010, 'M': 1, @@ -371,37 +372,37 @@ class PYSONTestCase(unittest.TestCase): self.assertRaises(AssertionError, pyson.Date, 2010, 1, 12, -1, 12, 'test') - self.assert_(pyson.Date(2010, 1, 12, -1, 12, -7).types() - == set([datetime.date])) + self.assertEqual(pyson.Date(2010, 1, 12, -1, 12, -7).types(), + set([datetime.date])) eval = pyson.PYSONEncoder().encode(pyson.Date()) - self.assert_(pyson.PYSONDecoder().decode(eval) - == datetime.date.today()) + self.assertEqual(pyson.PYSONDecoder().decode(eval), + datetime.date.today()) eval = pyson.PYSONEncoder().encode(pyson.Date(2010, 1, 12)) - self.assert_(pyson.PYSONDecoder().decode(eval) - == datetime.date(2010, 1, 12)) + self.assertEqual(pyson.PYSONDecoder().decode(eval), + datetime.date(2010, 1, 12)) eval = pyson.PYSONEncoder().encode(pyson.Date(2010, 1, 12, -1)) - self.assert_(pyson.PYSONDecoder().decode(eval) - == datetime.date(2009, 1, 12)) + self.assertEqual(pyson.PYSONDecoder().decode(eval), + datetime.date(2009, 1, 12)) eval = pyson.PYSONEncoder().encode(pyson.Date(2010, 1, 12, 0, 12)) - self.assert_(pyson.PYSONDecoder().decode(eval) - == datetime.date(2011, 1, 12)) + self.assertEqual(pyson.PYSONDecoder().decode(eval), + datetime.date(2011, 1, 12)) eval = pyson.PYSONEncoder().encode(pyson.Date(2010, 1, 12, 0, 0, -7)) - self.assert_(pyson.PYSONDecoder().decode(eval) - == datetime.date(2010, 1, 5)) + self.assertEqual(pyson.PYSONDecoder().decode(eval), + datetime.date(2010, 1, 5)) eval = pyson.PYSONEncoder().encode(datetime.date(2010, 2, 22)) - self.assert_(pyson.PYSONDecoder().decode(eval) - == datetime.date(2010, 2, 22)) + self.assertEqual(pyson.PYSONDecoder().decode(eval), + datetime.date(2010, 2, 22)) def test0130DateTime(self): 'Test pyson.DateTime' - self.assert_(pyson.DateTime(2010, 1, 12, 10, 30, 20, 0, - -1, 12, -7, 2, 15, 30, 1).pyson() == { + self.assertEqual(pyson.DateTime(2010, 1, 12, 10, 30, 20, 0, + -1, 12, -7, 2, 15, 30, 1).pyson(), { '__class__': 'DateTime', 'y': 2010, 'M': 1, @@ -448,64 +449,64 @@ class PYSONTestCase(unittest.TestCase): self.assertRaises(AssertionError, pyson.DateTime, 2010, 1, 12, 10, 30, 20, 0, -1, 12, -7, 2, 15, 30, 'test') - self.assert_(pyson.DateTime(2010, 1, 12, 10, 30, 20, 0, - -1, 12, -7, 2, 15, 30, 1).types() == set([datetime.datetime])) + self.assertEqual(pyson.DateTime(2010, 1, 12, 10, 30, 20, 0, + -1, 12, -7, 2, 15, 30, 1).types(), set([datetime.datetime])) eval = pyson.PYSONEncoder().encode(pyson.DateTime(2010, 1, 12, 10, 30, 20, 0)) - self.assert_(pyson.PYSONDecoder().decode(eval) - == datetime.datetime(2010, 1, 12, 10, 30, 20, 0)) + self.assertEqual(pyson.PYSONDecoder().decode(eval), + datetime.datetime(2010, 1, 12, 10, 30, 20, 0)) eval = pyson.PYSONEncoder().encode(pyson.DateTime(2010, 1, 12, 10, 30, 20, 0, -1)) - self.assert_(pyson.PYSONDecoder().decode(eval) - == datetime.datetime(2009, 1, 12, 10, 30, 20, 0)) + self.assertEqual(pyson.PYSONDecoder().decode(eval), + datetime.datetime(2009, 1, 12, 10, 30, 20, 0)) eval = pyson.PYSONEncoder().encode(pyson.DateTime(2010, 1, 12, 10, 30, 20, 0, 0, 12)) - self.assert_(pyson.PYSONDecoder().decode(eval) - == datetime.datetime(2011, 1, 12, 10, 30, 20, 0)) + self.assertEqual(pyson.PYSONDecoder().decode(eval), + datetime.datetime(2011, 1, 12, 10, 30, 20, 0)) eval = pyson.PYSONEncoder().encode(pyson.DateTime(2010, 1, 12, 10, 30, 20, 0, 0, 0, -7)) - self.assert_(pyson.PYSONDecoder().decode(eval) - == datetime.datetime(2010, 1, 5, 10, 30, 20, 0)) + self.assertEqual(pyson.PYSONDecoder().decode(eval), + datetime.datetime(2010, 1, 5, 10, 30, 20, 0)) eval = pyson.PYSONEncoder().encode(pyson.DateTime(2010, 1, 12, 10, 30, 20, 0, 0, 0, 0, 12)) - self.assert_(pyson.PYSONDecoder().decode(eval) - == datetime.datetime(2010, 1, 12, 22, 30, 20, 0)) + self.assertEqual(pyson.PYSONDecoder().decode(eval), + datetime.datetime(2010, 1, 12, 22, 30, 20, 0)) eval = pyson.PYSONEncoder().encode(pyson.DateTime(2010, 1, 12, 10, 30, 20, 0, 0, 0, 0, 0, -30)) - self.assert_(pyson.PYSONDecoder().decode(eval) - == datetime.datetime(2010, 1, 12, 10, 0, 20, 0)) + self.assertEqual(pyson.PYSONDecoder().decode(eval), + datetime.datetime(2010, 1, 12, 10, 0, 20, 0)) eval = pyson.PYSONEncoder().encode(pyson.DateTime(2010, 1, 12, 10, 30, 20, 0, 0, 0, 0, 0, 0, 30)) - self.assert_(pyson.PYSONDecoder().decode(eval) - == datetime.datetime(2010, 1, 12, 10, 30, 50, 0)) + self.assertEqual(pyson.PYSONDecoder().decode(eval), + datetime.datetime(2010, 1, 12, 10, 30, 50, 0)) eval = pyson.PYSONEncoder().encode(pyson.DateTime(2010, 1, 12, 10, 30, 20, 0, 0, 0, 0, 0, 0, 0, 200)) - self.assert_(pyson.PYSONDecoder().decode(eval) - == datetime.datetime(2010, 1, 12, 10, 30, 20, 200)) + self.assertEqual(pyson.PYSONDecoder().decode(eval), + datetime.datetime(2010, 1, 12, 10, 30, 20, 200)) eval = pyson.PYSONEncoder().encode(datetime.datetime( 2010, 2, 22, 10, 30, 20, 200)) - self.assert_(pyson.PYSONDecoder().decode(eval) - == datetime.datetime(2010, 2, 22, 10, 30, 20, 200)) + self.assertEqual(pyson.PYSONDecoder().decode(eval), + datetime.datetime(2010, 2, 22, 10, 30, 20, 200)) def test0140Len(self): 'Test pyson.Len' - self.assert_(pyson.Len([1, 2, 3]).pyson() == { + self.assertEqual(pyson.Len([1, 2, 3]).pyson(), { '__class__': 'Len', 'v': [1, 2, 3], }) self.assertRaises(AssertionError, pyson.Len, object()) - self.assert_(pyson.Len([1, 2, 3]).types() == set([int, long])) + self.assertEqual(pyson.Len([1, 2, 3]).types(), set([int])) eval = pyson.PYSONEncoder().encode(pyson.Len([1, 2, 3])) self.assertEqual(pyson.PYSONDecoder().decode(eval), 3) @@ -521,10 +522,10 @@ class PYSONTestCase(unittest.TestCase): eval = pyson.PYSONEncoder().encode(['id', pyson.If(pyson.Not( pyson.In('company', pyson.Eval('context', {}))), '=', '!='), pyson.Get(pyson.Eval('context', {}), 'company', -1)]) - self.assert_(pyson.PYSONDecoder({'context': {'company': 1}} - ).decode(eval) == ['id', '!=', 1]) - self.assert_(pyson.PYSONDecoder({'context': {}} - ).decode(eval) == ['id', '=', -1]) + self.assertEqual(pyson.PYSONDecoder({'context': {'company': 1}} + ).decode(eval), ['id', '!=', 1]) + self.assertEqual(pyson.PYSONDecoder({'context': {}} + ).decode(eval), ['id', '=', -1]) def suite():