Merge "Fix translation issue with interface inputs and functions"
This commit is contained in:
@@ -14,10 +14,10 @@ import collections
|
||||
import datetime
|
||||
import re
|
||||
|
||||
import toscaparser
|
||||
from toscaparser.common.exception import InvalidSchemaError
|
||||
from toscaparser.common.exception import ValidationError
|
||||
from toscaparser.elements import scalarunit
|
||||
from toscaparser.functions import is_function
|
||||
from toscaparser.utils.gettextutils import _
|
||||
|
||||
|
||||
@@ -262,7 +262,8 @@ class GreaterOrEqual(Constraint):
|
||||
'be comparable.'))
|
||||
|
||||
def _is_valid(self, value):
|
||||
if is_function(value) or value >= self.constraint_value:
|
||||
if toscaparser.functions.is_function(value) or \
|
||||
value >= self.constraint_value:
|
||||
return True
|
||||
return False
|
||||
|
||||
@@ -417,8 +418,8 @@ class ValidValues(Constraint):
|
||||
|
||||
def _err_msg(self, value):
|
||||
allowed = '[%s]' % ', '.join(str(a) for a in self.constraint_value)
|
||||
return (_('%(pname)s: %(pvalue)s is not an valid '
|
||||
'value "%(cvalue)s".') %
|
||||
return (_('%(pname)s: %(pvalue)s is not a valid value. Expected a '
|
||||
'value from "%(cvalue)s".') %
|
||||
dict(pname=self.property_name,
|
||||
pvalue=value,
|
||||
cvalue=allowed))
|
||||
|
||||
@@ -16,6 +16,7 @@ import abc
|
||||
import six
|
||||
|
||||
from toscaparser.common.exception import UnknownInputError
|
||||
from toscaparser.dataentity import DataEntity
|
||||
from toscaparser.utils.gettextutils import _
|
||||
|
||||
|
||||
@@ -80,9 +81,15 @@ class GetInput(Function):
|
||||
raise UnknownInputError(input_name=self.args[0])
|
||||
|
||||
def result(self):
|
||||
found_input = [input_def for input_def in self.tosca_tpl.inputs
|
||||
if self.input_name == input_def.name][0]
|
||||
return found_input.default
|
||||
if self.tosca_tpl.parsed_params and \
|
||||
self.input_name in self.tosca_tpl.parsed_params:
|
||||
return DataEntity.validate_datatype(
|
||||
self.tosca_tpl.tpl['inputs'][self.input_name]['type'],
|
||||
self.tosca_tpl.parsed_params[self.input_name])
|
||||
|
||||
input = [input_def for input_def in self.tosca_tpl.inputs
|
||||
if self.input_name == input_def.name][0]
|
||||
return input.default
|
||||
|
||||
@property
|
||||
def input_name(self):
|
||||
@@ -307,7 +314,7 @@ class GetProperty(Function):
|
||||
else:
|
||||
property_value = self._find_property(self.args[1]).value
|
||||
if isinstance(property_value, Function):
|
||||
return property_value
|
||||
return property_value.result()
|
||||
return get_function(self.tosca_tpl,
|
||||
self.context,
|
||||
property_value)
|
||||
|
||||
@@ -43,16 +43,14 @@ topology_template:
|
||||
properties:
|
||||
github_url: { get_input: github_url }
|
||||
requirements:
|
||||
- host:
|
||||
node: nodejs
|
||||
- database_connection:
|
||||
node: mongo_db
|
||||
- host: nodejs
|
||||
- database_connection: mongo_db
|
||||
interfaces:
|
||||
Standard:
|
||||
configure:
|
||||
implementation: ../Scripts/nodejs/config.sh
|
||||
inputs:
|
||||
github_url: http://github.com/paypal/rest-api-sample-app-nodejs.git
|
||||
github_url: { get_property: [ SELF, github_url ] }
|
||||
mongodb_ip: { get_attribute: [mongo_server, private_address] }
|
||||
start: ../Scripts/nodejs/start.sh
|
||||
nodejs:
|
||||
@@ -66,16 +64,14 @@ topology_template:
|
||||
mongo_db:
|
||||
type: tosca.nodes.Database
|
||||
requirements:
|
||||
- host:
|
||||
node: mongo_dbms
|
||||
- host: mongo_dbms
|
||||
interfaces:
|
||||
Standard:
|
||||
create: ../Scripts/mongodb/create_database.sh
|
||||
mongo_dbms:
|
||||
type: tosca.nodes.DBMS
|
||||
requirements:
|
||||
- host:
|
||||
node: mongo_server
|
||||
- host: mongo_server
|
||||
interfaces:
|
||||
Standard:
|
||||
create: ../Scripts/mongodb/create.sh
|
||||
@@ -87,8 +83,7 @@ topology_template:
|
||||
elasticsearch:
|
||||
type: tosca.nodes.SoftwareComponent.Elasticsearch
|
||||
requirements:
|
||||
- host:
|
||||
node: elasticsearch_server
|
||||
- host: elasticsearch_server
|
||||
interfaces:
|
||||
Standard:
|
||||
create: ../Scripts/elasticsearch/create.sh
|
||||
@@ -96,8 +91,7 @@ topology_template:
|
||||
logstash:
|
||||
type: tosca.nodes.SoftwareComponent.Logstash
|
||||
requirements:
|
||||
- host:
|
||||
node: logstash_server
|
||||
- host: logstash_server
|
||||
- search_endpoint:
|
||||
node: elasticsearch
|
||||
capability: search_endpoint
|
||||
@@ -116,11 +110,8 @@ topology_template:
|
||||
kibana:
|
||||
type: tosca.nodes.SoftwareComponent.Kibana
|
||||
requirements:
|
||||
- host:
|
||||
node: kibana_server
|
||||
- search_endpoint:
|
||||
node: elasticsearch
|
||||
capability: search_endpoint
|
||||
- host: kibana_server
|
||||
- search_endpoint: elasticsearch
|
||||
interfaces:
|
||||
Standard:
|
||||
create: ../Scripts/kibana/create.sh
|
||||
@@ -133,8 +124,7 @@ topology_template:
|
||||
app_collectd:
|
||||
type: tosca.nodes.SoftwareComponent.Collectd
|
||||
requirements:
|
||||
- host:
|
||||
node: app_server
|
||||
- host: app_server
|
||||
- log_endpoint:
|
||||
node: logstash
|
||||
capability: log_endpoint
|
||||
@@ -155,8 +145,7 @@ topology_template:
|
||||
app_rsyslog:
|
||||
type: tosca.nodes.SoftwareComponent.Rsyslog
|
||||
requirements:
|
||||
- host:
|
||||
node: app_server
|
||||
- host: app_server
|
||||
- log_endpoint:
|
||||
node: logstash
|
||||
capability: log_endpoint
|
||||
|
||||
@@ -33,10 +33,8 @@ topology_template:
|
||||
wordpress:
|
||||
type: tosca.nodes.WebApplication.WordPress
|
||||
requirements:
|
||||
- host:
|
||||
node: webserver
|
||||
- database_endpoint:
|
||||
node: mysql_database
|
||||
- host: webserver
|
||||
- database_endpoint: mysql_database
|
||||
interfaces:
|
||||
Standard:
|
||||
create: Scripts/WordPress/install.sh
|
||||
@@ -54,8 +52,7 @@ topology_template:
|
||||
user: { get_input: db_user }
|
||||
password: { get_input: db_pwd }
|
||||
requirements:
|
||||
- host:
|
||||
node: mysql_dbms
|
||||
- host: mysql_dbms
|
||||
interfaces:
|
||||
Standard:
|
||||
configure:
|
||||
@@ -72,8 +69,7 @@ topology_template:
|
||||
root_password: { get_input: db_root_pwd }
|
||||
port: { get_input: db_port }
|
||||
requirements:
|
||||
- host:
|
||||
node: server
|
||||
- host: server
|
||||
interfaces:
|
||||
Standard:
|
||||
create: Scripts/MYSQLDBMS/install.sh
|
||||
@@ -86,8 +82,7 @@ topology_template:
|
||||
webserver:
|
||||
type: tosca.nodes.WebServer
|
||||
requirements:
|
||||
- host:
|
||||
node: server
|
||||
- host: server
|
||||
interfaces:
|
||||
Standard:
|
||||
create: Scripts/WebServer/install.sh
|
||||
|
||||
@@ -51,7 +51,7 @@ topology_template:
|
||||
configure:
|
||||
implementation: nodejs/config.sh
|
||||
inputs:
|
||||
github_url: http://github.com/paypal/rest-api-sample-app-nodejs.git
|
||||
github_url: { get_property: [ SELF, github_url ] }
|
||||
mongodb_ip: { get_attribute: [mongo_server, private_address] }
|
||||
start: nodejs/start.sh
|
||||
nodejs:
|
||||
@@ -111,9 +111,7 @@ topology_template:
|
||||
type: tosca.nodes.SoftwareComponent.Kibana
|
||||
requirements:
|
||||
- host: kibana_server
|
||||
- search_endpoint:
|
||||
node: elasticsearch
|
||||
capability: search_endpoint
|
||||
- search_endpoint: elasticsearch
|
||||
interfaces:
|
||||
Standard:
|
||||
create: kibana/create.sh
|
||||
|
||||
@@ -46,9 +46,9 @@ topology_template:
|
||||
configure:
|
||||
implementation: wordpress/wordpress_configure.sh
|
||||
inputs:
|
||||
wp_db_name: wordpress
|
||||
wp_db_user: wp_user
|
||||
wp_db_password: wp_pass
|
||||
wp_db_name: { get_property: [ mysql_database, name ] }
|
||||
wp_db_user: { get_property: [ mysql_database, user ] }
|
||||
wp_db_password: { get_property: [ mysql_database, password ] }
|
||||
|
||||
mysql_database:
|
||||
type: tosca.nodes.Database
|
||||
@@ -61,17 +61,17 @@ topology_template:
|
||||
properties:
|
||||
port: { get_input: db_port }
|
||||
requirements:
|
||||
- host:
|
||||
node: mysql_dbms
|
||||
- host: mysql_dbms
|
||||
interfaces:
|
||||
Standard:
|
||||
configure:
|
||||
implementation: mysql/mysql_database_configure.sh
|
||||
inputs:
|
||||
db_name: wordpress
|
||||
db_user: wp_user
|
||||
db_password: wp_pass
|
||||
db_root_password: passw0rd
|
||||
db_name: { get_property: [ SELF, name ] }
|
||||
db_user: { get_property: [ SELF, user ] }
|
||||
db_password: { get_property: [ SELF, password ] }
|
||||
db_root_password: { get_property: [ mysql_dbms, root_password ] }
|
||||
|
||||
mysql_dbms:
|
||||
type: tosca.nodes.DBMS
|
||||
properties:
|
||||
@@ -84,12 +84,12 @@ topology_template:
|
||||
create:
|
||||
implementation: mysql/mysql_dbms_install.sh
|
||||
inputs:
|
||||
db_root_password: passw0rd
|
||||
db_root_password: { get_property: [ mysql_dbms, root_password ] }
|
||||
start: mysql/mysql_dbms_start.sh
|
||||
configure:
|
||||
implementation: mysql/mysql_dbms_configure.sh
|
||||
inputs:
|
||||
db_port: 3366
|
||||
db_port: { get_property: [ mysql_dbms, port ] }
|
||||
|
||||
webserver:
|
||||
type: tosca.nodes.WebServer
|
||||
@@ -99,6 +99,7 @@ topology_template:
|
||||
Standard:
|
||||
create: webserver/webserver_install.sh
|
||||
start: webserver/webserver_start.sh
|
||||
|
||||
server:
|
||||
type: tosca.nodes.Compute
|
||||
capabilities:
|
||||
|
||||
@@ -100,8 +100,8 @@ class ConstraintTest(TestCase):
|
||||
constraint = Constraint('prop', Schema.INTEGER, schema)
|
||||
error = self.assertRaises(exception.ValidationError,
|
||||
constraint.validate, 5)
|
||||
self.assertEqual('prop: 5 is not an valid value "[2, 4, 6, 8]".',
|
||||
str(error))
|
||||
self.assertEqual('prop: 5 is not a valid value. Expected a value from '
|
||||
'"[2, 4, 6, 8]".', str(error))
|
||||
|
||||
def test_invalid_in_range(self):
|
||||
snippet = 'in_range: {2, 6}'
|
||||
|
||||
@@ -221,7 +221,7 @@ class DataTypeTest(TestCase):
|
||||
data = DataEntity('tosca.my.datatypes.PeopleBase', value,
|
||||
DataTypeTest.custom_type_def)
|
||||
error = self.assertRaises(ValueError, data.validate)
|
||||
self.assertEqual('"123" is not a string', error.__str__())
|
||||
self.assertEqual('"123" is not a string.', error.__str__())
|
||||
|
||||
# the value of name doesn't meet the defined constraint
|
||||
def test_value_error_in_dataentity(self):
|
||||
@@ -247,7 +247,7 @@ class DataTypeTest(TestCase):
|
||||
data = DataEntity('tosca.my.datatypes.People', value,
|
||||
DataTypeTest.custom_type_def)
|
||||
error = self.assertRaises(ValueError, data.validate)
|
||||
self.assertEqual('"1" is not a string', error.__str__())
|
||||
self.assertEqual('"1" is not a string.', error.__str__())
|
||||
|
||||
# contact_pone is an invalid field name in nested datatype
|
||||
def test_validation_in_nested_datatype(self):
|
||||
@@ -289,11 +289,11 @@ class DataTypeTest(TestCase):
|
||||
"data/datatypes/test_custom_datatypes_value_error.yaml")
|
||||
error = self.assertRaises(ValueError, ToscaTemplate, tpl_path)
|
||||
self.assertEqual('"[\'1 foo street\', \'9 bar avenue\']" '
|
||||
'is not a map', error.__str__())
|
||||
'is not a map.', error.__str__())
|
||||
|
||||
def test_datatype_in_template_nested_datatype_error(self):
|
||||
tpl_path = os.path.join(
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
"data/datatypes/test_custom_datatypes_nested_datatype_error.yaml")
|
||||
error = self.assertRaises(ValueError, ToscaTemplate, tpl_path)
|
||||
self.assertEqual('"123456789" is not a string', error.__str__())
|
||||
self.assertEqual('"123456789" is not a string.', error.__str__())
|
||||
|
||||
@@ -23,7 +23,8 @@ class IntrinsicFunctionsTest(TestCase):
|
||||
tosca_tpl = os.path.join(
|
||||
os.path.dirname(os.path.abspath(__file__)),
|
||||
"data/tosca_single_instance_wordpress.yaml")
|
||||
tosca = ToscaTemplate(tosca_tpl)
|
||||
params = {'db_name': 'my_wordpress', 'db_user': 'my_db_user'}
|
||||
tosca = ToscaTemplate(tosca_tpl, parsed_params=params)
|
||||
|
||||
def _get_node(self, node_name):
|
||||
return [
|
||||
@@ -39,34 +40,30 @@ class IntrinsicFunctionsTest(TestCase):
|
||||
return [prop.value for prop in node_template.get_properties_objects()
|
||||
if prop.name == property_name][0]
|
||||
|
||||
def test_get_property(self):
|
||||
TestCase.skip(self, 'bug #1440247')
|
||||
mysql_dbms = self._get_node('mysql_dbms')
|
||||
operation = self._get_operation(mysql_dbms.interfaces, 'configure')
|
||||
db_root_password = operation.inputs['db_root_password']
|
||||
self.assertTrue(isinstance(db_root_password, functions.GetProperty))
|
||||
result = db_root_password.result()
|
||||
self.assertTrue(isinstance(result, functions.GetInput))
|
||||
def _get_inputs_dict(self):
|
||||
inputs = {}
|
||||
for input in self.tosca.inputs:
|
||||
inputs[input.name] = input.default
|
||||
return inputs
|
||||
|
||||
def test_get_requirement_property(self):
|
||||
TestCase.skip(self, 'bug #1440247')
|
||||
def _get_input(self, name):
|
||||
self._get_inputs_dict()[name]
|
||||
|
||||
def test_get_property(self):
|
||||
wordpress = self._get_node('wordpress')
|
||||
operation = self._get_operation(wordpress.interfaces, 'configure')
|
||||
wp_db_port = operation.inputs['wp_db_port']
|
||||
self.assertTrue(isinstance(wp_db_port, functions.GetProperty))
|
||||
result = wp_db_port.result()
|
||||
self.assertTrue(isinstance(result, functions.GetInput))
|
||||
self.assertEqual('db_port', result.input_name)
|
||||
wp_db_password = operation.inputs['wp_db_password']
|
||||
self.assertTrue(isinstance(wp_db_password, functions.GetProperty))
|
||||
result = wp_db_password.result()
|
||||
self.assertEqual('wp_pass', result)
|
||||
|
||||
def test_get_capability_property(self):
|
||||
TestCase.skip(self, 'bug #1440247')
|
||||
mysql_database = self._get_node('mysql_database')
|
||||
operation = self._get_operation(mysql_database.interfaces, 'configure')
|
||||
db_port = operation.inputs['db_port']
|
||||
self.assertTrue(isinstance(db_port, functions.GetProperty))
|
||||
result = db_port.result()
|
||||
self.assertTrue(isinstance(result, functions.GetInput))
|
||||
self.assertEqual('db_port', result.input_name)
|
||||
def test_get_property_with_input_param(self):
|
||||
wordpress = self._get_node('wordpress')
|
||||
operation = self._get_operation(wordpress.interfaces, 'configure')
|
||||
wp_db_user = operation.inputs['wp_db_user']
|
||||
self.assertTrue(isinstance(wp_db_user, functions.GetProperty))
|
||||
result = wp_db_user.result()
|
||||
self.assertEqual('my_db_user', result)
|
||||
|
||||
def test_unknown_capability_property(self):
|
||||
err = self.assertRaises(
|
||||
@@ -87,13 +84,6 @@ class IntrinsicFunctionsTest(TestCase):
|
||||
expected_inputs.remove(prop.value.input_name)
|
||||
self.assertListEqual(expected_inputs, [])
|
||||
|
||||
def test_get_input_in_interface(self):
|
||||
TestCase.skip(self, 'bug #1440247')
|
||||
mysql_dbms = self._get_node('mysql_dbms')
|
||||
operation = self._get_operation(mysql_dbms.interfaces, 'configure')
|
||||
db_user = operation.inputs['db_user']
|
||||
self.assertTrue(isinstance(db_user, functions.GetInput))
|
||||
|
||||
def test_get_input_validation(self):
|
||||
self.assertRaises(exception.UnknownInputError,
|
||||
self._load_template,
|
||||
|
||||
@@ -44,7 +44,7 @@ class PropertyTest(TestCase):
|
||||
propertyInstance = Property('test_property', 'a',
|
||||
test_property_schema)
|
||||
error = self.assertRaises(ValueError, propertyInstance.validate)
|
||||
self.assertEqual('"a" is not a list', str(error))
|
||||
self.assertEqual('"a" is not a list.', str(error))
|
||||
|
||||
def test_list_entry_schema(self):
|
||||
test_property_schema = {'type': 'list',
|
||||
@@ -73,8 +73,7 @@ class PropertyTest(TestCase):
|
||||
propertyInstance = Property('test_property', [1, 'b'],
|
||||
test_property_schema)
|
||||
error = self.assertRaises(ValueError, propertyInstance.validate)
|
||||
self.assertEqual('"b" is not an integer',
|
||||
str(error))
|
||||
self.assertEqual('"b" is not an integer.', str(error))
|
||||
|
||||
def test_map(self):
|
||||
test_property_schema = {'type': 'map'}
|
||||
@@ -88,7 +87,7 @@ class PropertyTest(TestCase):
|
||||
propertyInstance = Property('test_property', 12,
|
||||
test_property_schema)
|
||||
error = self.assertRaises(ValueError, propertyInstance.validate)
|
||||
self.assertEqual('"12" is not a map', str(error))
|
||||
self.assertEqual('"12" is not a map.', str(error))
|
||||
|
||||
def test_map_entry_schema(self):
|
||||
test_property_schema = {'type': 'map',
|
||||
@@ -107,7 +106,7 @@ class PropertyTest(TestCase):
|
||||
{'valid': True, 'contact_name': 123},
|
||||
test_property_schema)
|
||||
error = self.assertRaises(ValueError, propertyInstance.validate)
|
||||
self.assertEqual('"123" is not a boolean', str(error))
|
||||
self.assertEqual('"123" is not a boolean.', str(error))
|
||||
|
||||
def test_boolean(self):
|
||||
test_property_schema = {'type': 'boolean'}
|
||||
@@ -124,7 +123,7 @@ class PropertyTest(TestCase):
|
||||
propertyInstance = Property('test_property', 12,
|
||||
test_property_schema)
|
||||
error = self.assertRaises(ValueError, propertyInstance.validate)
|
||||
self.assertEqual('"12" is not a boolean', str(error))
|
||||
self.assertEqual('"12" is not a boolean.', str(error))
|
||||
|
||||
def test_float(self):
|
||||
test_property_schema = {'type': 'float'}
|
||||
@@ -138,7 +137,7 @@ class PropertyTest(TestCase):
|
||||
propertyInstance = Property('test_property', 12,
|
||||
test_property_schema)
|
||||
error = self.assertRaises(ValueError, propertyInstance.validate)
|
||||
self.assertEqual('"12" is not a float', str(error))
|
||||
self.assertEqual('"12" is not a float.', str(error))
|
||||
|
||||
def test_timestamp(self):
|
||||
test_property_schema = {'type': 'timestamp'}
|
||||
|
||||
@@ -68,7 +68,7 @@ class ToscaTemplateTest(TestCase):
|
||||
expected_type = "tosca.nodes.Database"
|
||||
expected_properties = ['name', 'password', 'user']
|
||||
expected_capabilities = ['database_endpoint']
|
||||
expected_requirements = [{'host': {'node': 'mysql_dbms'}}]
|
||||
expected_requirements = [{'host': 'mysql_dbms'}]
|
||||
''' TODO: needs enhancement in tosca_elk.yaml..
|
||||
expected_relationshp = ['tosca.relationships.HostedOn']
|
||||
expected_host = ['mysql_dbms']
|
||||
|
||||
@@ -730,7 +730,7 @@ custom_types/wordpress.yaml
|
||||
capability: log_endpoint
|
||||
occurrences: [a, w]
|
||||
'''
|
||||
expectedmessage = ('"a" is not an integer')
|
||||
expectedmessage = ('"a" is not an integer.')
|
||||
err = self.assertRaises(
|
||||
ValueError,
|
||||
lambda: self._single_node_template_content_test(tpl_snippet))
|
||||
@@ -745,7 +745,7 @@ custom_types/wordpress.yaml
|
||||
capability: log_endpoint
|
||||
occurrences: -1
|
||||
'''
|
||||
expectedmessage = ('"-1" is not a list')
|
||||
expectedmessage = ('"-1" is not a list.')
|
||||
err = self.assertRaises(
|
||||
ValueError,
|
||||
lambda: self._single_node_template_content_test(tpl_snippet))
|
||||
@@ -1000,7 +1000,7 @@ custom_types/wordpress.yaml
|
||||
lambda: self._single_node_template_content_test(tpl_snippet))
|
||||
self.assertEqual(expectedmessage, err.__str__())
|
||||
|
||||
# validatating capability property values
|
||||
# validating capability property values
|
||||
tpl_snippet = '''
|
||||
node_templates:
|
||||
server:
|
||||
@@ -1010,8 +1010,8 @@ custom_types/wordpress.yaml
|
||||
properties:
|
||||
initiator: test
|
||||
'''
|
||||
expectedmessage = ('initiator: test is not an valid value '
|
||||
'"[source, target, peer]".')
|
||||
expectedmessage = ('initiator: test is not a valid value. Expected a '
|
||||
'value from "[source, target, peer]".')
|
||||
|
||||
err = self.assertRaises(
|
||||
exception.ValidationError,
|
||||
|
||||
@@ -42,31 +42,31 @@ def validate_integer(value):
|
||||
try:
|
||||
value = int(value)
|
||||
except Exception:
|
||||
raise ValueError(_('"%s" is not an integer') % value)
|
||||
raise ValueError(_('"%s" is not an integer.') % value)
|
||||
return value
|
||||
|
||||
|
||||
def validate_float(value):
|
||||
if not isinstance(value, float):
|
||||
raise ValueError(_('"%s" is not a float') % value)
|
||||
raise ValueError(_('"%s" is not a float.') % value)
|
||||
return validate_number(value)
|
||||
|
||||
|
||||
def validate_string(value):
|
||||
if not isinstance(value, six.string_types):
|
||||
raise ValueError(_('"%s" is not a string') % value)
|
||||
raise ValueError(_('"%s" is not a string.') % value)
|
||||
return value
|
||||
|
||||
|
||||
def validate_list(value):
|
||||
if not isinstance(value, list):
|
||||
raise ValueError(_('"%s" is not a list') % value)
|
||||
raise ValueError(_('"%s" is not a list.') % value)
|
||||
return value
|
||||
|
||||
|
||||
def validate_map(value):
|
||||
if not isinstance(value, collections.Mapping):
|
||||
raise ValueError(_('"%s" is not a map') % value)
|
||||
raise ValueError(_('"%s" is not a map.') % value)
|
||||
return value
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ def validate_boolean(value):
|
||||
normalised = value.lower()
|
||||
if normalised in ['true', 'false']:
|
||||
return normalised == 'true'
|
||||
raise ValueError(_('"%s" is not a boolean') % value)
|
||||
raise ValueError(_('"%s" is not a boolean.') % value)
|
||||
|
||||
|
||||
def validate_timestamp(value):
|
||||
|
||||
Reference in New Issue
Block a user