Add __repr__ to PYSON
issue4607 review4151002
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
* Add __repr__ to PYSON
|
||||
* Remove safe_eval
|
||||
* Add ModelView.view_attributes
|
||||
* Add pyson attribute on data field tag
|
||||
|
||||
@@ -95,6 +95,14 @@ class PYSON(object):
|
||||
def contains(self, k):
|
||||
return In(k, self)
|
||||
|
||||
def __repr__(self):
|
||||
klass = self.__class__.__name__
|
||||
return '%s(%s)' % (klass, ', '.join(map(repr, self.__repr_params__)))
|
||||
|
||||
@property
|
||||
def __repr_params__(self):
|
||||
return NotImplementedError
|
||||
|
||||
|
||||
class PYSONEncoder(json.JSONEncoder):
|
||||
|
||||
@@ -132,6 +140,10 @@ class Eval(PYSON):
|
||||
self._value = value
|
||||
self._default = default
|
||||
|
||||
@property
|
||||
def __repr_params__(self):
|
||||
return self._value, self._default
|
||||
|
||||
def pyson(self):
|
||||
return {
|
||||
'__class__': 'Eval',
|
||||
@@ -161,6 +173,10 @@ class Not(PYSON):
|
||||
assert isinstance(value, bool), 'value must be boolean'
|
||||
self._value = value
|
||||
|
||||
@property
|
||||
def __repr_params__(self):
|
||||
return (self._value,)
|
||||
|
||||
def pyson(self):
|
||||
return {
|
||||
'__class__': 'Not',
|
||||
@@ -181,6 +197,10 @@ class Bool(PYSON):
|
||||
super(Bool, self).__init__()
|
||||
self._value = value
|
||||
|
||||
@property
|
||||
def __repr_params__(self):
|
||||
return (self._value,)
|
||||
|
||||
def pyson(self):
|
||||
return {
|
||||
'__class__': 'Bool',
|
||||
@@ -209,6 +229,10 @@ class And(PYSON):
|
||||
assert len(statements) >= 2, 'must have at least 2 statements'
|
||||
self._statements = list(statements)
|
||||
|
||||
@property
|
||||
def __repr_params__(self):
|
||||
return tuple(self._statements)
|
||||
|
||||
def pyson(self):
|
||||
return {
|
||||
'__class__': 'And',
|
||||
@@ -251,6 +275,10 @@ class Equal(PYSON):
|
||||
self._statement1 = statement1
|
||||
self._statement2 = statement2
|
||||
|
||||
@property
|
||||
def __repr_params__(self):
|
||||
return (self._statement1, self._statement2)
|
||||
|
||||
def pyson(self):
|
||||
return {
|
||||
'__class__': 'Equal',
|
||||
@@ -285,6 +313,10 @@ class Greater(PYSON):
|
||||
self._statement2 = statement2
|
||||
self._equal = equal
|
||||
|
||||
@property
|
||||
def __repr_params__(self):
|
||||
return (self._statement1, self._statement2, self._equal)
|
||||
|
||||
def pyson(self):
|
||||
return {
|
||||
'__class__': 'Greater',
|
||||
@@ -352,6 +384,10 @@ class If(PYSON):
|
||||
self._then_statement = then_statement
|
||||
self._else_statement = else_statement
|
||||
|
||||
@property
|
||||
def __repr_params__(self):
|
||||
return (self._condition, self._then_statement, self._else_statement)
|
||||
|
||||
def pyson(self):
|
||||
return {
|
||||
'__class__': 'If',
|
||||
@@ -391,6 +427,10 @@ class Get(PYSON):
|
||||
self._key = key
|
||||
self._default = default
|
||||
|
||||
@property
|
||||
def __repr_params__(self):
|
||||
return (self._obj, self._key, self._default)
|
||||
|
||||
def pyson(self):
|
||||
return {
|
||||
'__class__': 'Get',
|
||||
@@ -433,6 +473,10 @@ class In(PYSON):
|
||||
self._key = key
|
||||
self._obj = obj
|
||||
|
||||
@property
|
||||
def __repr_params__(self):
|
||||
return (self._key, self._obj)
|
||||
|
||||
def pyson(self):
|
||||
return {
|
||||
'__class__': 'In',
|
||||
@@ -467,6 +511,11 @@ class Date(PYSON):
|
||||
self._delta_months = delta_months
|
||||
self._delta_days = delta_days
|
||||
|
||||
@property
|
||||
def __repr_params__(self):
|
||||
return (self._year, self._month, self._day,
|
||||
self._delta_years, self._delta_months, self._delta_days)
|
||||
|
||||
def pyson(self):
|
||||
return {
|
||||
'__class__': 'Date',
|
||||
@@ -520,6 +569,15 @@ class DateTime(Date):
|
||||
self._delta_seconds = delta_seconds
|
||||
self._delta_microseconds = delta_microseconds
|
||||
|
||||
@property
|
||||
def __repr_params__(self):
|
||||
date_params = super(DateTime, self).__repr_params__
|
||||
return (date_params[:3]
|
||||
+ (self._hour, self._minute, self._second, self._microsecond)
|
||||
+ date_params[3:]
|
||||
+ (self._delta_hours, self._delta_minutes, self._delta_seconds,
|
||||
self._delta_microseconds))
|
||||
|
||||
def pyson(self):
|
||||
res = super(DateTime, self).pyson()
|
||||
res['__class__'] = 'DateTime'
|
||||
@@ -568,6 +626,10 @@ class Len(PYSON):
|
||||
'value must be a dict or list or a string'
|
||||
self._value = value
|
||||
|
||||
@property
|
||||
def __repr_params__(self):
|
||||
return (self._value,)
|
||||
|
||||
def pyson(self):
|
||||
return {
|
||||
'__class__': 'Len',
|
||||
@@ -590,6 +652,10 @@ class Id(PYSON):
|
||||
self._module = module
|
||||
self._fs_id = fs_id
|
||||
|
||||
@property
|
||||
def __repr_params__(self):
|
||||
return (self._module, self._fs_id)
|
||||
|
||||
def pyson(self):
|
||||
from trytond.pool import Pool
|
||||
ModelData = Pool().get('ir.model.data')
|
||||
|
||||
@@ -30,6 +30,9 @@ class PYSONTestCase(unittest.TestCase):
|
||||
self.assertEqual(pyson.PYSONDecoder({'test': 1}).decode(eval), 1)
|
||||
self.assertEqual(pyson.PYSONDecoder().decode(eval), 0)
|
||||
|
||||
self.assertEqual(repr(pyson.Eval('test', 'foo')),
|
||||
"Eval('test', 'foo')")
|
||||
|
||||
def test0020Not(self):
|
||||
'Test pyson.Not'
|
||||
self.assertEqual(pyson.Not(True).pyson(), {
|
||||
@@ -47,6 +50,8 @@ class PYSONTestCase(unittest.TestCase):
|
||||
eval = pyson.PYSONEncoder().encode(pyson.Not(False))
|
||||
self.assertTrue(pyson.PYSONDecoder().decode(eval))
|
||||
|
||||
self.assertEqual(repr(pyson.Not(True)), 'Not(True)')
|
||||
|
||||
def test0030Bool(self):
|
||||
'Test pyson.Bool'
|
||||
self.assertEqual(pyson.Bool('test').pyson(), {
|
||||
@@ -86,6 +91,8 @@ class PYSONTestCase(unittest.TestCase):
|
||||
eval = pyson.PYSONEncoder().encode(pyson.Bool({}))
|
||||
self.assertFalse(pyson.PYSONDecoder().decode(eval))
|
||||
|
||||
self.assertEqual(repr(pyson.Bool('test')), "Bool('test')")
|
||||
|
||||
def test0040And(self):
|
||||
'Test pyson.And'
|
||||
self.assertEqual(pyson.And(True, False).pyson(), {
|
||||
@@ -128,6 +135,9 @@ class PYSONTestCase(unittest.TestCase):
|
||||
eval = pyson.PYSONEncoder().encode(pyson.And(False, False, True))
|
||||
self.assertFalse(pyson.PYSONDecoder().decode(eval))
|
||||
|
||||
self.assertEqual(repr(pyson.And(False, True, True)),
|
||||
'And(False, True, True)')
|
||||
|
||||
def test0050Or(self):
|
||||
'Test pyson.Or'
|
||||
self.assertEqual(pyson.Or(True, False).pyson(), {
|
||||
@@ -170,6 +180,9 @@ class PYSONTestCase(unittest.TestCase):
|
||||
eval = pyson.PYSONEncoder().encode(pyson.Or(False, False, True))
|
||||
self.assertTrue(pyson.PYSONDecoder().decode(eval))
|
||||
|
||||
self.assertEqual(repr(pyson.Or(False, True, True)),
|
||||
'Or(False, True, True)')
|
||||
|
||||
def test0060Equal(self):
|
||||
'Test pyson.Equal'
|
||||
self.assertEqual(pyson.Equal('test', 'test').pyson(), {
|
||||
@@ -188,6 +201,9 @@ class PYSONTestCase(unittest.TestCase):
|
||||
eval = pyson.PYSONEncoder().encode(pyson.Equal('foo', 'bar'))
|
||||
self.assertFalse(pyson.PYSONDecoder().decode(eval))
|
||||
|
||||
self.assertEqual(repr(pyson.Equal('foo', 'bar')),
|
||||
"Equal('foo', 'bar')")
|
||||
|
||||
def test0070Greater(self):
|
||||
'Test pyson.Greater'
|
||||
self.assertEqual(pyson.Greater(1, 0).pyson(), {
|
||||
@@ -221,6 +237,8 @@ class PYSONTestCase(unittest.TestCase):
|
||||
eval = pyson.PYSONEncoder().encode(pyson.Greater(1, 1, True))
|
||||
self.assertTrue(pyson.PYSONDecoder().decode(eval))
|
||||
|
||||
self.assertEqual(repr(pyson.Greater(1, 0)), 'Greater(1, 0, False)')
|
||||
|
||||
def test0080Less(self):
|
||||
'Test pyson.Less'
|
||||
self.assertEqual(pyson.Less(0, 1).pyson(), {
|
||||
@@ -254,6 +272,8 @@ class PYSONTestCase(unittest.TestCase):
|
||||
eval = pyson.PYSONEncoder().encode(pyson.Less(1, 1, True))
|
||||
self.assertTrue(pyson.PYSONDecoder().decode(eval))
|
||||
|
||||
self.assertEqual(repr(pyson.Less(0, 1)), 'Less(0, 1, False)')
|
||||
|
||||
def test0090If(self):
|
||||
'Test pyson.If'
|
||||
self.assertEqual(pyson.If(True, 'foo', 'bar').pyson(), {
|
||||
@@ -276,6 +296,9 @@ class PYSONTestCase(unittest.TestCase):
|
||||
eval = pyson.PYSONEncoder().encode(pyson.If(False, 'foo', 'bar'))
|
||||
self.assertEqual(pyson.PYSONDecoder().decode(eval), 'bar')
|
||||
|
||||
self.assertEqual(repr(pyson.If(True, 'foo', 'bar')),
|
||||
"If(True, 'foo', 'bar')")
|
||||
|
||||
def test0100Get(self):
|
||||
'Test pyson.Get'
|
||||
self.assertEqual(pyson.Get({'foo': 'bar'}, 'foo', 'default').pyson(), {
|
||||
@@ -304,6 +327,9 @@ class PYSONTestCase(unittest.TestCase):
|
||||
{}, 'foo', 'default'))
|
||||
self.assertEqual(pyson.PYSONDecoder().decode(eval), 'default')
|
||||
|
||||
self.assertEqual(repr(pyson.Get({'foo': 'bar'}, 'foo', 'default')),
|
||||
"Get({'foo': 'bar'}, 'foo', 'default')")
|
||||
|
||||
def test0110In(self):
|
||||
'Test pyson.In'
|
||||
self.assertEqual(pyson.In('foo', {'foo': 'bar'}).pyson(), {
|
||||
@@ -347,6 +373,9 @@ class PYSONTestCase(unittest.TestCase):
|
||||
eval = pyson.PYSONEncoder().encode(pyson.In('test', []))
|
||||
self.assertFalse(pyson.PYSONDecoder().decode(eval))
|
||||
|
||||
self.assertEqual(repr(pyson.In('foo', ['foo', 'bar'])),
|
||||
"In('foo', ['foo', 'bar'])")
|
||||
|
||||
def test0120Date(self):
|
||||
'Test pyson.Date'
|
||||
self.assertEqual(pyson.Date(2010, 1, 12, -1, 12, -7).pyson(), {
|
||||
@@ -399,6 +428,9 @@ class PYSONTestCase(unittest.TestCase):
|
||||
self.assertEqual(pyson.PYSONDecoder().decode(eval),
|
||||
datetime.date(2010, 2, 22))
|
||||
|
||||
self.assertEqual(repr(pyson.Date(2010, 1, 12, -1, 12, -7)),
|
||||
'Date(2010, 1, 12, -1, 12, -7)')
|
||||
|
||||
def test0130DateTime(self):
|
||||
'Test pyson.DateTime'
|
||||
self.assertEqual(pyson.DateTime(2010, 1, 12, 10, 30, 20, 0,
|
||||
@@ -497,6 +529,10 @@ class PYSONTestCase(unittest.TestCase):
|
||||
self.assertEqual(pyson.PYSONDecoder().decode(eval),
|
||||
datetime.datetime(2010, 2, 22, 10, 30, 20, 200))
|
||||
|
||||
self.assertEqual(repr(pyson.DateTime(2010, 1, 12, 10, 30, 20, 0,
|
||||
-1, 12, -7, 2, 15, 30, 1)),
|
||||
'DateTime(2010, 1, 12, 10, 30, 20, 0, -1, 12, -7, 2, 15, 30, 1)')
|
||||
|
||||
def test0140Len(self):
|
||||
'Test pyson.Len'
|
||||
self.assertEqual(pyson.Len([1, 2, 3]).pyson(), {
|
||||
@@ -517,16 +553,22 @@ class PYSONTestCase(unittest.TestCase):
|
||||
eval = pyson.PYSONEncoder().encode(pyson.Len('foo bar'))
|
||||
self.assertEqual(pyson.PYSONDecoder().decode(eval), 7)
|
||||
|
||||
self.assertEqual(repr(pyson.Len([1, 2, 3])), 'Len([1, 2, 3])')
|
||||
|
||||
def test0900Composite(self):
|
||||
'Test Composite'
|
||||
eval = pyson.PYSONEncoder().encode(['id', pyson.If(pyson.Not(
|
||||
pyson.In('company', pyson.Eval('context', {}))), '=', '!='),
|
||||
expr = pyson.If(pyson.Not(
|
||||
pyson.In('company', pyson.Eval('context', {}))), '=', '!=')
|
||||
eval = pyson.PYSONEncoder().encode(['id', expr,
|
||||
pyson.Get(pyson.Eval('context', {}), 'company', -1)])
|
||||
self.assertEqual(pyson.PYSONDecoder({'context': {'company': 1}}
|
||||
).decode(eval), ['id', '!=', 1])
|
||||
self.assertEqual(pyson.PYSONDecoder({'context': {}}
|
||||
).decode(eval), ['id', '=', -1])
|
||||
|
||||
self.assertEqual(repr(expr),
|
||||
"If(Not(In('company', Eval('context', {}))), '=', '!=')")
|
||||
|
||||
|
||||
def suite():
|
||||
return unittest.TestLoader().loadTestsFromTestCase(PYSONTestCase)
|
||||
|
||||
Reference in New Issue
Block a user