Allow SQL expression as value of fields
issue6460 review279431002
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
* Allow SQL expression as value of fields
|
||||
* Allow customizing Dict keys order with a sequence field
|
||||
* Add invalid domain in DomainValidationError
|
||||
* Add domain inversion tools
|
||||
|
||||
@@ -10,6 +10,7 @@ class Boolean(Field):
|
||||
'''
|
||||
_type = 'boolean'
|
||||
_sql_type = 'BOOL'
|
||||
_py_type = bool
|
||||
|
||||
def __init__(self, string='', help='', readonly=False, domain=None,
|
||||
states=None, select=False, on_change=None, on_change_with=None,
|
||||
|
||||
@@ -12,6 +12,7 @@ class Char(FieldTranslate):
|
||||
Define a char field (``unicode``).
|
||||
'''
|
||||
_type = 'char'
|
||||
_py_type = str
|
||||
|
||||
def __init__(self, string='', size=None, help='', required=False,
|
||||
readonly=False, domain=None, states=None, translate=False,
|
||||
@@ -47,12 +48,6 @@ class Char(FieldTranslate):
|
||||
|
||||
size = property(_get_size, _set_size)
|
||||
|
||||
def sql_format(self, value):
|
||||
if value is None:
|
||||
return None
|
||||
assert isinstance(value, str)
|
||||
return value
|
||||
|
||||
@property
|
||||
def _sql_type(self):
|
||||
return 'VARCHAR(%s)' % self.size if self.size else 'VARCHAR'
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
# this repository contains the full copyright notices and license terms.
|
||||
import datetime
|
||||
|
||||
from sql.functions import Function
|
||||
|
||||
from trytond.pyson import PYSONEncoder
|
||||
@@ -29,23 +30,16 @@ class Date(Field):
|
||||
'''
|
||||
_type = 'date'
|
||||
_sql_type = 'DATE'
|
||||
_py_type = datetime.date
|
||||
|
||||
def sql_format(self, value):
|
||||
if value is None:
|
||||
return None
|
||||
if isinstance(value, str):
|
||||
year, month, day = list(map(int, value.split("-", 2)))
|
||||
return datetime.date(year, month, day)
|
||||
|
||||
if (not isinstance(value, datetime.date)
|
||||
# Allow datetime with min time for XML-RPC
|
||||
# datetime must be tested separately because datetime is a
|
||||
# subclass of date
|
||||
or (isinstance(value, datetime.datetime)
|
||||
and value.time() != datetime.time())):
|
||||
raise ValueError("invalid type '%s' for %s"
|
||||
% (type(value), type(self)))
|
||||
return value
|
||||
value = datetime.date(year, month, day)
|
||||
elif isinstance(value, datetime.datetime):
|
||||
if value.time() != datetime.time():
|
||||
raise ValueError("Date field can not have time")
|
||||
return super().sql_format(value)
|
||||
|
||||
def sql_cast(self, expression):
|
||||
if backend.name() == 'sqlite':
|
||||
@@ -68,11 +62,10 @@ class Timestamp(FormatMixin, Field):
|
||||
'''
|
||||
_type = 'timestamp'
|
||||
_sql_type = 'TIMESTAMP'
|
||||
_py_type = datetime.datetime
|
||||
format = '%H:%M:%S.%f'
|
||||
|
||||
def sql_format(self, value):
|
||||
if value is None:
|
||||
return None
|
||||
if isinstance(value, str):
|
||||
datepart, timepart = value.split(" ")
|
||||
year, month, day = map(int, datepart.split("-", 2))
|
||||
@@ -82,12 +75,9 @@ class Timestamp(FormatMixin, Field):
|
||||
microseconds = int(timepart_full[1])
|
||||
else:
|
||||
microseconds = 0
|
||||
return datetime.datetime(year, month, day, hours, minutes, seconds,
|
||||
microseconds)
|
||||
if not isinstance(value, datetime.datetime):
|
||||
raise ValueError("invalid type '%s' for %s"
|
||||
% (type(value), type(self)))
|
||||
return value
|
||||
value = datetime.datetime(
|
||||
year, month, day, hours, minutes, seconds, microseconds)
|
||||
return super().sql_format(value)
|
||||
|
||||
def sql_cast(self, expression):
|
||||
if backend.name() == 'sqlite':
|
||||
@@ -119,28 +109,40 @@ class DateTime(Timestamp):
|
||||
|
||||
def sql_format(self, value):
|
||||
value = super().sql_format(value)
|
||||
if value:
|
||||
if isinstance(value, datetime.datetime):
|
||||
value = value.replace(microsecond=0)
|
||||
return value
|
||||
|
||||
|
||||
class Time(DateTime):
|
||||
class Time(FormatMixin, Field):
|
||||
'''
|
||||
Define a time field (``time``).
|
||||
'''
|
||||
_type = 'time'
|
||||
_sql_type = 'TIME'
|
||||
_py_type = datetime.time
|
||||
|
||||
def __init__(self, string='', format='%H:%M:%S', help='', required=False,
|
||||
readonly=False, domain=None, states=None, select=False,
|
||||
on_change=None, on_change_with=None, depends=None,
|
||||
context=None, loading='eager'):
|
||||
'''
|
||||
:param format: The validation format as used by strftime.
|
||||
'''
|
||||
super().__init__(string=string, help=help,
|
||||
required=required, readonly=readonly, domain=domain, states=states,
|
||||
select=select, on_change=on_change, on_change_with=on_change_with,
|
||||
depends=depends, context=context, loading=loading)
|
||||
self.format = format
|
||||
|
||||
def sql_format(self, value):
|
||||
if value is None:
|
||||
return None
|
||||
if isinstance(value, str):
|
||||
hours, minutes, seconds = map(int, value.split(":"))
|
||||
return datetime.time(hours, minutes, seconds)
|
||||
if not isinstance(value, datetime.time):
|
||||
raise ValueError("invalid type '%s' for %s"
|
||||
% (type(value), type(self)))
|
||||
return value.replace(microsecond=0)
|
||||
value = datetime.time(hours, minutes, seconds)
|
||||
value = super().sql_format(value)
|
||||
if isinstance(value, datetime.time):
|
||||
value = value.replace(microsecond=0)
|
||||
return value
|
||||
|
||||
def sql_cast(self, expression):
|
||||
if backend.name() == 'sqlite':
|
||||
@@ -154,6 +156,7 @@ class TimeDelta(Field):
|
||||
'''
|
||||
_type = 'timedelta'
|
||||
_sql_type = 'INTERVAL'
|
||||
_py_type = datetime.timedelta
|
||||
|
||||
def __init__(self, string='', converter=None, help='', required=False,
|
||||
readonly=False, domain=None, states=None, select=False,
|
||||
@@ -170,12 +173,9 @@ class TimeDelta(Field):
|
||||
self.converter = converter
|
||||
|
||||
def sql_format(self, value):
|
||||
if value is None:
|
||||
return None
|
||||
if not isinstance(value, datetime.timedelta):
|
||||
raise ValueError("invalid type '%s' for %s"
|
||||
% (type(value), type(self)))
|
||||
return super(TimeDelta, self).sql_format(value)
|
||||
if isinstance(value, (int, float)):
|
||||
raise TypeError("TimeDelta requires a timedelta")
|
||||
return super().sql_format(value)
|
||||
|
||||
@classmethod
|
||||
def get(cls, ids, model, name, values=None):
|
||||
|
||||
@@ -21,6 +21,7 @@ class Dict(Field):
|
||||
'Define dict field.'
|
||||
_type = 'dict'
|
||||
_sql_type = 'TEXT'
|
||||
_py_type = dict
|
||||
|
||||
def __init__(self, schema_model, string='', help='', required=False,
|
||||
readonly=False, domain=None, states=None, select=False,
|
||||
@@ -44,11 +45,10 @@ class Dict(Field):
|
||||
return dicts
|
||||
|
||||
def sql_format(self, value):
|
||||
if value is None:
|
||||
return None
|
||||
assert isinstance(value, dict)
|
||||
value = {k: v for k, v in value.items() if v is not None}
|
||||
return dumps(value)
|
||||
value = super().sql_format(value)
|
||||
if isinstance(value, dict):
|
||||
value = dumps({k: v for k, v in value.items() if v is not None})
|
||||
return value
|
||||
|
||||
def translated(self, name=None, type_='values'):
|
||||
"Return a descriptor for the translated value of the field"
|
||||
|
||||
@@ -210,6 +210,7 @@ SQL_OPERATORS = {
|
||||
class Field(object):
|
||||
_type = None
|
||||
_sql_type = None
|
||||
_py_type = None
|
||||
|
||||
def __init__(self, string='', help='', required=False, readonly=False,
|
||||
domain=None, states=None, select=False, on_change=None,
|
||||
@@ -343,6 +344,9 @@ class Field(object):
|
||||
|
||||
assert self._sql_type is not None
|
||||
database = Transaction().database
|
||||
if (self._py_type and value is not None
|
||||
and not isinstance(value, self._py_type)):
|
||||
value = self._py_type(value)
|
||||
return database.sql_format(self._sql_type, value)
|
||||
|
||||
def sql_type(self):
|
||||
|
||||
@@ -22,6 +22,7 @@ class Float(Field):
|
||||
'''
|
||||
_type = 'float'
|
||||
_sql_type = 'FLOAT'
|
||||
_py_type = float
|
||||
|
||||
def __init__(self, string='', digits=None, help='', required=False,
|
||||
readonly=False, domain=None, states=None, select=False,
|
||||
@@ -49,11 +50,6 @@ class Float(Field):
|
||||
|
||||
digits = property(_get_digits, _set_digits)
|
||||
|
||||
def sql_format(self, value):
|
||||
if value is None:
|
||||
return None
|
||||
return float(value)
|
||||
|
||||
def definition(self, model, language):
|
||||
encoder = PYSONEncoder()
|
||||
definition = super().definition(model, language)
|
||||
|
||||
@@ -9,11 +9,7 @@ class Integer(Field):
|
||||
'''
|
||||
_type = 'integer'
|
||||
_sql_type = 'INTEGER'
|
||||
|
||||
def sql_format(self, value):
|
||||
if value is None:
|
||||
return None
|
||||
return int(str(value))
|
||||
_py_type = int
|
||||
|
||||
|
||||
class BigInteger(Integer):
|
||||
|
||||
@@ -19,6 +19,7 @@ class Many2One(Field):
|
||||
'''
|
||||
_type = 'many2one'
|
||||
_sql_type = 'INTEGER'
|
||||
_py_type = int
|
||||
|
||||
def __init__(self, model_name, string='', left=None, right=None,
|
||||
ondelete='SET NULL', datetime_field=None, target_search='join',
|
||||
@@ -111,10 +112,8 @@ class Many2One(Field):
|
||||
super(Many2One, self).__set__(inst, value)
|
||||
|
||||
def sql_format(self, value):
|
||||
if value is None:
|
||||
return None
|
||||
assert value is not False
|
||||
return int(value)
|
||||
return super().sql_format(value)
|
||||
|
||||
def convert_domain_mptt(self, domain, tables):
|
||||
cursor = Transaction().connection.cursor()
|
||||
|
||||
@@ -20,14 +20,7 @@ class Numeric(Float):
|
||||
'''
|
||||
_type = 'numeric'
|
||||
_sql_type = 'NUMERIC'
|
||||
|
||||
def sql_format(self, value):
|
||||
if value is None:
|
||||
return None
|
||||
if isinstance(value, int):
|
||||
value = Decimal(str(value))
|
||||
value = Decimal(value)
|
||||
return value
|
||||
_py_type = Decimal
|
||||
|
||||
def sql_column(self, table):
|
||||
column = super(Numeric, self).sql_column(table)
|
||||
|
||||
@@ -20,6 +20,7 @@ class Reference(SelectionMixin, Field):
|
||||
'''
|
||||
_type = 'reference'
|
||||
_sql_type = 'VARCHAR'
|
||||
_py_type = str
|
||||
|
||||
def __init__(self, string='', selection=None, sort=True,
|
||||
selection_change_with=None, translate=True, search_order=None,
|
||||
|
||||
@@ -59,6 +59,7 @@ class Selection(SelectionMixin, Field):
|
||||
'''
|
||||
_type = 'selection'
|
||||
_sql_type = 'VARCHAR'
|
||||
_py_type = str
|
||||
|
||||
def __init__(self, selection, string='', sort=True,
|
||||
selection_change_with=None, translate=True, help='',
|
||||
|
||||
@@ -35,10 +35,17 @@ class TimeFormat(ModelSQL):
|
||||
time = fields.Time(string='Time', format='%H:%M')
|
||||
|
||||
|
||||
class TimePrecision(ModelSQL):
|
||||
"Time precision"
|
||||
__name__ = 'test.time_precision'
|
||||
time = fields.Time(string="Time", format="%H:%M:%S.%f")
|
||||
|
||||
|
||||
def register(module):
|
||||
Pool.register(
|
||||
Time,
|
||||
TimeDefault,
|
||||
TimeRequired,
|
||||
TimeFormat,
|
||||
TimePrecision,
|
||||
module=module, type_='model')
|
||||
|
||||
@@ -4,6 +4,8 @@ import shutil
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
from sql import Literal
|
||||
|
||||
from trytond.config import config
|
||||
from trytond.model.exceptions import RequiredValidationError
|
||||
from trytond.model import fields
|
||||
@@ -110,6 +112,17 @@ class FieldBinaryTestCase(unittest.TestCase):
|
||||
self.assertEqual(binary.binary, None)
|
||||
self.assertEqual(binary.binary_id, None)
|
||||
|
||||
@with_transaction()
|
||||
def test_create_with_sql_value(self):
|
||||
"Test create binary with SQL value"
|
||||
Binary = Pool().get('test.binary')
|
||||
|
||||
binary, = Binary.create([{
|
||||
'binary': Literal('foo'),
|
||||
}])
|
||||
|
||||
self.assertEqual(binary.binary, cast(b'foo'))
|
||||
|
||||
@with_transaction()
|
||||
def test_read_size(self):
|
||||
"Test read binary size"
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
# this repository contains the full copyright notices and license terms.
|
||||
import unittest
|
||||
|
||||
from sql import Literal
|
||||
|
||||
from trytond.pool import Pool
|
||||
from trytond.tests.test_tryton import activate_module, with_transaction
|
||||
|
||||
@@ -48,6 +50,15 @@ class FieldBooleanTestCase(unittest.TestCase):
|
||||
|
||||
self.assertEqual(boolean.boolean, True)
|
||||
|
||||
@with_transaction()
|
||||
def test_create_with_sql_value(self):
|
||||
"Test create boolean with SQL value"
|
||||
Boolean = Pool().get('test.boolean')
|
||||
|
||||
boolean, = Boolean.create([{'boolean': Literal(True)}])
|
||||
|
||||
self.assertEqual(boolean.boolean, True)
|
||||
|
||||
@with_transaction()
|
||||
def test_search_equals_true(self):
|
||||
"Test search boolean equals True"
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
# this repository contains the full copyright notices and license terms.
|
||||
import unittest
|
||||
|
||||
from sql import Literal
|
||||
|
||||
from trytond import backend
|
||||
from trytond.model.exceptions import RequiredValidationError
|
||||
from trytond.pool import Pool
|
||||
@@ -37,6 +39,15 @@ class CommonTestCaseMixin:
|
||||
|
||||
self.assertEqual(char.char, "é")
|
||||
|
||||
@with_transaction()
|
||||
def test_create_with_sql_value(self):
|
||||
"Test create with SQL value"
|
||||
Char = self.Char()
|
||||
|
||||
char, = Char.create([{'char': Literal('Foo')}])
|
||||
|
||||
self.assertEqual(char.char, "Foo")
|
||||
|
||||
@with_transaction()
|
||||
def test_search_equals(self):
|
||||
"Test search char equals"
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
import datetime
|
||||
import unittest
|
||||
|
||||
from sql.functions import CurrentDate
|
||||
|
||||
from trytond.model.exceptions import RequiredValidationError
|
||||
from trytond.pool import Pool
|
||||
from trytond.tests.test_tryton import activate_module, with_transaction
|
||||
@@ -73,6 +75,15 @@ class FieldDateTestCase(unittest.TestCase):
|
||||
|
||||
self.assertEqual(date.date, default_date)
|
||||
|
||||
@with_transaction()
|
||||
def test_create_with_sql_value(self):
|
||||
"Test create date with SQL value"
|
||||
Date = Pool().get('test.date')
|
||||
|
||||
date, = Date.create([{'date': CurrentDate()}])
|
||||
|
||||
self.assert_(date.date)
|
||||
|
||||
@with_transaction()
|
||||
def test_create_non_date(self):
|
||||
"Test create date with non date"
|
||||
@@ -88,7 +99,7 @@ class FieldDateTestCase(unittest.TestCase):
|
||||
"Test create date with integer"
|
||||
Date = Pool().get('test.date')
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
with self.assertRaises(TypeError):
|
||||
Date.create([{
|
||||
'date': 42,
|
||||
}])
|
||||
@@ -413,7 +424,7 @@ class FieldDateTestCase(unittest.TestCase):
|
||||
'date': today,
|
||||
}])
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
with self.assertRaises(TypeError):
|
||||
Date.write([date], {
|
||||
'date': 42,
|
||||
})
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
import datetime
|
||||
import unittest
|
||||
|
||||
from sql.functions import CurrentTimestamp
|
||||
|
||||
from trytond.model.exceptions import (
|
||||
RequiredValidationError, TimeFormatValidationError)
|
||||
from trytond.pool import Pool
|
||||
@@ -74,6 +76,17 @@ class FieldDateTimeTestCase(unittest.TestCase):
|
||||
|
||||
self.assertEqual(datetime.datetime, default_datetime)
|
||||
|
||||
@with_transaction()
|
||||
def test_create_with_sql_value(self):
|
||||
"Test create datetime with SQL value"
|
||||
DateTime = Pool().get('test.datetime')
|
||||
|
||||
datetime, = DateTime.create([{
|
||||
'datetime': DateTime.datetime.sql_cast(CurrentTimestamp()),
|
||||
}])
|
||||
|
||||
self.assert_(datetime.datetime)
|
||||
|
||||
@with_transaction()
|
||||
def test_create_non_datetime(self):
|
||||
"Test create datetime with non datetime"
|
||||
@@ -89,7 +102,7 @@ class FieldDateTimeTestCase(unittest.TestCase):
|
||||
"Test create datetime with integer"
|
||||
DateTime = Pool().get('test.datetime')
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
with self.assertRaises(TypeError):
|
||||
DateTime.create([{
|
||||
'datetime': 42,
|
||||
}])
|
||||
@@ -99,7 +112,7 @@ class FieldDateTimeTestCase(unittest.TestCase):
|
||||
"Test create datetime with date"
|
||||
DateTime = Pool().get('test.datetime')
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
with self.assertRaises(TypeError):
|
||||
DateTime.create([{
|
||||
'datetime': datetime.date(2009, 1, 1),
|
||||
}])
|
||||
@@ -447,7 +460,7 @@ class FieldDateTimeTestCase(unittest.TestCase):
|
||||
'datetime': today,
|
||||
}])
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
with self.assertRaises(TypeError):
|
||||
DateTime.write([datetime], {
|
||||
'datetime': 42,
|
||||
})
|
||||
@@ -460,7 +473,7 @@ class FieldDateTimeTestCase(unittest.TestCase):
|
||||
'datetime': today,
|
||||
}])
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
with self.assertRaises(TypeError):
|
||||
DateTime.write([datetime_], {
|
||||
'datetime': datetime.date(2009, 1, 1),
|
||||
})
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
# this repository contains the full copyright notices and license terms.
|
||||
import unittest
|
||||
|
||||
from sql import Literal
|
||||
|
||||
from trytond.model.exceptions import (
|
||||
RequiredValidationError, DigitsValidationError)
|
||||
from trytond.pool import Pool
|
||||
@@ -58,6 +60,15 @@ class FieldFloatTestCase(unittest.TestCase):
|
||||
|
||||
self.assertEqual(float_.float, 5.5)
|
||||
|
||||
@with_transaction()
|
||||
def test_create_with_sql_value(self):
|
||||
"Test create float with SQL value"
|
||||
Float = Pool().get('test.float')
|
||||
|
||||
float_, = Float.create([{'float': Literal(5.) / Literal(2.)}])
|
||||
|
||||
self.assertEqual(float_.float, 2.5)
|
||||
|
||||
@with_transaction()
|
||||
def test_create_non_float(self):
|
||||
"Test create float with non float"
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
# this repository contains the full copyright notices and license terms.
|
||||
import unittest
|
||||
|
||||
from sql import Literal
|
||||
|
||||
from trytond.model.exceptions import (
|
||||
RequiredValidationError, DomainValidationError)
|
||||
from trytond.pool import Pool
|
||||
@@ -47,6 +49,15 @@ class FieldIntegerTestCase(unittest.TestCase):
|
||||
|
||||
self.assertEqual(integer.integer, 5)
|
||||
|
||||
@with_transaction()
|
||||
def test_create_with_sql_value(self):
|
||||
"Test create integer with SQL value"
|
||||
Integer = Pool().get('test.integer_default')
|
||||
|
||||
integer, = Integer.create([{'integer': Literal(5)}])
|
||||
|
||||
self.assertEqual(integer.integer, 5)
|
||||
|
||||
@with_transaction()
|
||||
def test_create_non_integer(self):
|
||||
"Test create integer with non integer"
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
import unittest
|
||||
from decimal import Decimal, InvalidOperation
|
||||
|
||||
from sql import Literal
|
||||
|
||||
from trytond.model.exceptions import (
|
||||
RequiredValidationError, DigitsValidationError)
|
||||
from trytond.pool import Pool
|
||||
@@ -59,6 +61,15 @@ class FieldNumericTestCase(unittest.TestCase):
|
||||
|
||||
self.assertEqual(numeric.numeric, Decimal('5.5'))
|
||||
|
||||
@with_transaction()
|
||||
def test_create_with_sql_value(self):
|
||||
"Test create numeric with SQL value"
|
||||
Numeric = Pool().get('test.numeric')
|
||||
|
||||
numeric, = Numeric.create([{'numeric': Literal(5.) / Literal(2.)}])
|
||||
|
||||
self.assertEqual(numeric.numeric, Decimal('2.5'))
|
||||
|
||||
@with_transaction()
|
||||
def test_create_non_numeric(self):
|
||||
"Test create numeric with non numeric"
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
import datetime
|
||||
import unittest
|
||||
|
||||
from sql.functions import CurrentTimestamp
|
||||
|
||||
from trytond.model.exceptions import (
|
||||
RequiredValidationError, TimeFormatValidationError)
|
||||
from trytond.pool import Pool
|
||||
@@ -74,6 +76,15 @@ class FieldTimeTestCase(unittest.TestCase):
|
||||
|
||||
self.assertEqual(time.time, default_time)
|
||||
|
||||
@with_transaction()
|
||||
def test_create_with_sql_value(self):
|
||||
"Test create time with SQL value"
|
||||
Time = Pool().get('test.time_precision')
|
||||
|
||||
time, = Time.create([{'time': Time.time.sql_cast(CurrentTimestamp())}])
|
||||
|
||||
self.assert_(time.time)
|
||||
|
||||
@with_transaction()
|
||||
def test_create_non_time(self):
|
||||
"Test create time with non time"
|
||||
@@ -99,7 +110,7 @@ class FieldTimeTestCase(unittest.TestCase):
|
||||
"Test create time with date"
|
||||
Time = Pool().get('test.time')
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
with self.assertRaises(TypeError):
|
||||
Time.create([{
|
||||
'time': datetime.date(2009, 1, 1),
|
||||
}])
|
||||
@@ -460,7 +471,7 @@ class FieldTimeTestCase(unittest.TestCase):
|
||||
'time': evening,
|
||||
}])
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
with self.assertRaises(TypeError):
|
||||
Time.write([time], {
|
||||
'time': datetime.date(2009, 1, 1),
|
||||
})
|
||||
|
||||
@@ -57,7 +57,7 @@ class FieldTimeDeltaTestCase(unittest.TestCase):
|
||||
"Test create timedelta with non timedelta"
|
||||
TimeDelta = Pool().get('test.timedelta')
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
with self.assertRaises(TypeError):
|
||||
TimeDelta.create([{
|
||||
'timedelta': 'non timedelta',
|
||||
}])
|
||||
@@ -67,7 +67,7 @@ class FieldTimeDeltaTestCase(unittest.TestCase):
|
||||
"Test create timedelta with integer"
|
||||
TimeDelta = Pool().get('test.timedelta')
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
with self.assertRaises(TypeError):
|
||||
TimeDelta.create([{
|
||||
'timedelta': 42,
|
||||
}])
|
||||
@@ -369,7 +369,7 @@ class FieldTimeDeltaTestCase(unittest.TestCase):
|
||||
'timedelta': hour,
|
||||
}])
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
with self.assertRaises(TypeError):
|
||||
TimeDelta.write([timedelta], {
|
||||
'timedelta': 'non timedelta',
|
||||
})
|
||||
@@ -382,7 +382,7 @@ class FieldTimeDeltaTestCase(unittest.TestCase):
|
||||
'timedelta': hour,
|
||||
}])
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
with self.assertRaises(TypeError):
|
||||
TimeDelta.write([timedelta], {
|
||||
'timedelta': 42,
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user