Add a name to the checkeddict to improve the error messages

Change-Id: I11edc3bce77cd84d0393d6d95c6733b7901f95a1
Signed-off-by: Angus Salkeld <asalkeld@redhat.com>
This commit is contained in:
Angus Salkeld 2012-05-30 13:10:02 +10:00
parent a5962d1078
commit afa0d4cf0b
4 changed files with 31 additions and 23 deletions

View File

@ -19,8 +19,9 @@ import re
class CheckedDict(collections.MutableMapping): class CheckedDict(collections.MutableMapping):
def __init__(self): def __init__(self, name):
self.data = {} self.data = {}
self.name = name
def addschema(self, key, schema): def addschema(self, key, schema):
self.data[key] = schema self.data[key] = schema
@ -44,28 +45,31 @@ class CheckedDict(collections.MutableMapping):
'Float': float} 'Float': float}
if not key in self.data: if not key in self.data:
raise KeyError('key %s not found' % key) raise KeyError('%s: key %s not found' % (self.name, key))
if 'Type' in self.data[key]: if 'Type' in self.data[key]:
t = self.data[key]['Type'] t = self.data[key]['Type']
if self.data[key]['Type'] == 'String': if self.data[key]['Type'] == 'String':
if not isinstance(value, (basestring, unicode)): if not isinstance(value, (basestring, unicode)):
raise ValueError('%s Value must be a string' % \ raise ValueError('%s: %s Value must be a string' % \
(key)) (self.name, key))
if 'MaxLength' in self.data[key]: if 'MaxLength' in self.data[key]:
if len(value) > int(self.data[key]['MaxLength']): if len(value) > int(self.data[key]['MaxLength']):
raise ValueError('%s is too long; MaxLength %s' % \ raise ValueError('%s: %s is too long; MaxLength %s' % \
(key, self.data[key]['MaxLength'])) (self.name, key,
self.data[key]['MaxLength']))
if 'MinLength' in self.data[key]: if 'MinLength' in self.data[key]:
if len(value) < int(self.data[key]['MinLength']): if len(value) < int(self.data[key]['MinLength']):
raise ValueError('%s is too short; MinLength %s' % \ raise ValueError('%s: %s is too short; MinLength %s' %\
(key, self.data[key]['MinLength'])) (self.name, key,
self.data[key]['MinLength']))
if 'AllowedPattern' in self.data[key]: if 'AllowedPattern' in self.data[key]:
rc = re.match('^%s$' % self.data[key]['AllowedPattern'], rc = re.match('^%s$' % self.data[key]['AllowedPattern'],
value) value)
if rc == None: if rc == None:
raise ValueError('Pattern does not match %s' % \ raise ValueError('%s: Pattern %s does not match %s' % \
(key)) (self.name, self.data[key]['AllowedPattern'],
key))
elif self.data[key]['Type'] in ['Integer', 'Number', 'Float']: elif self.data[key]['Type'] in ['Integer', 'Number', 'Float']:
# just try convert and see if it will throw a ValueError # just try convert and see if it will throw a ValueError
@ -77,27 +81,31 @@ class CheckedDict(collections.MutableMapping):
if 'MinValue' in self.data[key]: if 'MinValue' in self.data[key]:
minn = num_converter[t](self.data[key]['MinValue']) minn = num_converter[t](self.data[key]['MinValue'])
if num > maxn or num < minn: if num > maxn or num < minn:
raise ValueError('%s is out of range' % key) raise ValueError('%s: %s is out of range' % (self.name,
key))
elif self.data[key]['Type'] == 'List': elif self.data[key]['Type'] == 'List':
if not isinstance(value, list): if not isinstance(value, list):
raise ValueError('%s Value must be a list' % (key)) raise ValueError('%s: %s Value must be a list' % \
(self.name, key))
elif self.data[key]['Type'] == 'CommaDelimitedList': elif self.data[key]['Type'] == 'CommaDelimitedList':
sp = value.split(',') sp = value.split(',')
if not isinstance(sp, list): if not isinstance(sp, list):
raise ValueError('%s Value must be a list' % (key)) raise ValueError('%s: %s Value must be a list' % \
(self.name, key))
if 'AllowedValues' in self.data[key]: if 'AllowedValues' in self.data[key]:
if not value in self.data[key]['AllowedValues']: if not value in self.data[key]['AllowedValues']:
raise ValueError('Value must be one of %s' % \ raise ValueError('%s: %s Value must be one of %s' % \
str(self.data[key]['AllowedValues'])) (self.name, key,
str(self.data[key]['AllowedValues'])))
self.data[key]['Value'] = value self.data[key]['Value'] = value
def __getitem__(self, key): def __getitem__(self, key):
if not key in self.data: if not key in self.data:
raise KeyError('key %s not found' % key) raise KeyError('%s: key %s not found' % (self.name, key))
if 'Value' in self.data[key]: if 'Value' in self.data[key]:
return self.data[key]['Value'] return self.data[key]['Value']
@ -107,9 +115,9 @@ class CheckedDict(collections.MutableMapping):
if not self.data[key]['Required']: if not self.data[key]['Required']:
return None return None
else: else:
raise ValueError('%s must be provided' % key) raise ValueError('%s: %s must be provided' % (self.name, key))
else: else:
raise ValueError('%s must be provided' % key) raise ValueError('%s: %s must be provided' % (self.name, key))
def __len__(self): def __len__(self):
return len(self.data) return len(self.data)
@ -125,8 +133,8 @@ class CheckedDict(collections.MutableMapping):
class Properties(CheckedDict): class Properties(CheckedDict):
def __init__(self, schema): def __init__(self, name, schema):
CheckedDict.__init__(self) CheckedDict.__init__(self, name)
self.data = schema self.data = schema
# set some defaults # set some defaults

View File

@ -72,7 +72,7 @@ class Stack(object):
self.metadata_server = metadata_server self.metadata_server = metadata_server
# Default Parameters # Default Parameters
self.parms = checkeddict.CheckedDict() self.parms = checkeddict.CheckedDict('Parameters')
self.parms.addschema('AWS::StackName', {"Description": "AWS StackName", self.parms.addschema('AWS::StackName', {"Description": "AWS StackName",
"Type": "String"}) "Type": "String"})
self.parms['AWS::StackName'] = stack_name self.parms['AWS::StackName'] = stack_name

View File

@ -50,7 +50,7 @@ class Resource(object):
self.references = [] self.references = []
self.stack = stack self.stack = stack
self.name = name self.name = name
self.properties = checkeddict.Properties(self.properties_schema) self.properties = checkeddict.Properties(name, self.properties_schema)
if not 'Properties' in self.t: if not 'Properties' in self.t:
# make a dummy entry to prevent having to check all over the # make a dummy entry to prevent having to check all over the
# place for it. # place for it.

View File

@ -51,7 +51,7 @@ class CheckedDictTest(unittest.TestCase):
} }
''' '''
ps = json.loads(parms) ps = json.loads(parms)
cd = checkeddict.CheckedDict() cd = checkeddict.CheckedDict('test_paramerters')
for p in ps['Parameters']: for p in ps['Parameters']:
cd.addschema(p, ps['Parameters'][p]) cd.addschema(p, ps['Parameters'][p])