Compare commits

...

4 Commits

Author SHA1 Message Date
Nicholas Hope a7552fad96 A few more changes 2022-10-02 12:13:04 -04:00
Nicholas Hope f483beb0bd Made it prettier 2022-10-02 12:12:55 -04:00
Nicholas Hope f0dac0d1a1 Just, a ton of work. Aded literals 2022-10-02 12:12:33 -04:00
Nicholas Hope 0bbca21fea Added warnings 2022-10-02 12:12:15 -04:00
5 changed files with 307 additions and 185 deletions

View File

@ -26,11 +26,11 @@ default:
# hold doubles
double r:
condition: mouse4
cancel: both
type: hold
primary: +class_action
secondary: +reload
condition: mouse4
cancel: both
# other
impulse =: kill
@ -60,26 +60,26 @@ default:
press:
- "-moveright"
- "+moveleft"
- "alias maybeMoveLeft +moveleft"
- "alias maybe_move_left +moveleft"
release:
- "-moveleft"
- "maybeMoveRight"
- "alias maybeMoveLeft "
- "maybe_move_right"
- "unalias maybe_move_left"
hold d:
press:
- "-moveleft"
- "+moveright"
- "alias maybeMoveRight +moveright"
- "alias maybe_move_right +moveright"
release:
- "-moveright"
- "maybeMoveLeft"
- "alias maybeMoveRight "
- "maybe_move_left"
- "unalias maybe_move_right"
# This just stops an error message the first time you release
# either of 'a' or 'd'
impulse maybeMoveLeft:
impulse maybe_move_left:
alias: yes
command: ""
impulse maybeMoveRight:
impulse maybe_move_right:
alias: yes
command: ""
# class action is something useful for each class,
@ -97,16 +97,16 @@ default:
impulse load0:
alias: yes
command: "load_itempreset a"
command: "loadout a"
impulse load1:
alias: yes
command: "load_itempreset b"
command: "loadout b"
impulse load2:
alias: yes
command: "load_itempreset c"
command: "loadout c"
impulse load3:
alias: yes
command: "load_itempreset d"
command: "loadout d"
impulse INS:
- "load0"
@ -120,8 +120,10 @@ default:
impulse END:
- "load3"
- "alias reload_presets load3"
literal set_default_loadout:
alias reload_presets load0
impulse backspace:
"reload_presets"
reload_presets
engi:
hold class_action:
@ -129,7 +131,6 @@ engi:
press:
- destroy sentry
- build sentry
release: ""
medic:
# "Radar" feature: causes all teammates to autocall for medic, allowing

View File

@ -1,15 +1,15 @@
""" This has only one function. It mostly exists to allow imports of things like tftypes """
from copy import deepcopy
from tfscript.tftypes import double
from tfscript.tftypes import Double
def makeCFG(bindList, default=False):
if default:
# Write to defaultDict instead of condDict
double.condDict = double.defaultDict
Double.condDict = Double.defaultDict
else:
double.condDict = deepcopy(double.defaultDict)
Double.condDict = deepcopy(Double.defaultDict)
ret = ''
@ -18,14 +18,16 @@ def makeCFG(bindList, default=False):
# Doubles are weird. All of the toggles got put into a dictionary.
# This takes all of the nested dictionaries and turns them into the right string
if default or double.condDict != double.defaultDict:
if default or Double.condDict != Double.defaultDict:
# ==, and by extension !=, does in fact check
# for dictionary equality in keys and values
for key, toggles in double.condDict.items():
for key, toggles in Double.condDict.items():
onCondPress = ';'.join(toggles["change_keys"])
onCondRelease = ';'.join(toggles["restore_keys"])
ret += f'alias +{key}_toggles "{onCondPress}"\n' +\
f'alias -{key}_toggles "{onCondRelease}"\n' +\
f'bind {key} "+{key}_toggles"\n'
ret += (
f'alias +{key}_toggles "{onCondPress}"\n'
+ f'alias -{key}_toggles "{onCondRelease}"\n'
+ f'bind {key} "+{key}_toggles"\n'
)
return ret

View File

@ -38,6 +38,12 @@ def parseFile(inputFile) -> (dict, dict):
# See verify.py
config, defaults = verify.verifyConfig(config)
if 'warnings' in config:
for cclass, messages in config.pop('warnings').items():
print(f'Warning in {cclass}:', file=stderr)
for msg in messages:
print(f' {msg}', file=stderr)
if 'errors' in config:
for cclass, messages in config['errors'].items():
print(f'Error in {cclass}:', file=stderr)

View File

@ -1,3 +1,5 @@
import re
validKeyList = [
# top row
'escape', 'f1', 'f2', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9', 'f10', 'f11', 'f12',
@ -18,7 +20,9 @@ validKeyList = [
'leftarrow', 'rightarrow'
]
class bind(object):
popErrors = (AttributeError, KeyError, TypeError)
class Bind(object):
'''
Parent class for all bind types.
Verifies key, creates local variables
@ -26,18 +30,26 @@ class bind(object):
bindTypes = []
instances = {}
def __init__(self, key, fields):
self.alias = False
self.key = key
self.fields = fields
self.errors = []
self.targetType = None
def __init__(self, key='', fields={}, *, parent=None):
if parent is None:
self.alias = False
self.key = str(key)
self.fields = fields
self.errors = []
self.warnings = []
self.TargetType = None
else:
self.alias = parent.alias
self.key = parent.key
self.fields = parent.fields
self.errors = parent.errors
self.warnings = parent.warnings
# redefined for each unique type, default just verifies key
# and some other universal fields like alias and finds targetType
self.verify()
if type(self) is bind:
if type(self) is Bind:
# not using isinstance(), because all subclasses are also instances
# of bind.
return
@ -46,15 +58,15 @@ class bind(object):
# verify function should remove all fields relavent to the bind.
# Any extras are errors
self.errors.append(f'extra fields in "{self.key}":')
self.warnings.append(f'extra fields in "{self.key}":')
if isinstance(self.fields, str):
# iterating over a str returns each character,
# making meaningless error messages
self.errors.append(f' "{self.fields}"')
self.warnings.append(f' "{self.fields}"')
else:
for field in self.fields:
self.errors.append(f' "{field}"')
elif len(self.errors) == 0:
self.warnings.append(f' "{field}"')
if len(self.errors) == 0:
# no errors, add new instance to the list of instances
try:
self.instances[type(self)].append(self)
@ -62,20 +74,20 @@ class bind(object):
self.instances[type(self)] = [self]
def verify(self):
try:
self.alias = self.fields.pop('alias')
if not isinstance(self.alias, bool):
self.errors.append(f'alias should be "yes" or "no", not "{self.alias}"')
self.errors.append(
f'alias should be "yes" or "no", not "{self.alias}"'
)
self.alias = False
except (KeyError, AttributeError, TypeError):
# KeyError, if dict but no alias field;
# AttributeError, if no pop method;
# TypeError, if pop method won't take str() as arg
except popErrors:
self.alias = False
try:
typeName, self.key = self.key.split(' ', 1)
# all types start with a capital
typeName = typeName.lower().capitalize()
if not self.alias:
# don't mess with alias names
self.key = self.key.lower()
@ -84,33 +96,39 @@ class bind(object):
self.errors.append(f'could not find type in "{self.key}"')
return
for type_ in self.bindTypes:
if typeName == type_.__name__:
self.TargetType = type_
break
if self.TargetType is None:
self.errors.append(
f'"{typeName}" is not a valid type for "{self.key}"'
)
if (not self.alias) and (self.key not in validKeyList):
self.errors.append(f'invalid key name: "{self.key}"')
for type_ in self.bindTypes:
if typeName == type_.__name__:
self.targetType = type_
break
if self.targetType is None:
self.errors.append(f'could not find type in "{self.key}"')
def toTargetType(self):
if self.targetType is None:
if self.TargetType is None:
# do nothing
bind = self
else:
# cast to targetType, extend errors
bind = self.targetType(self.key, self.fields)
bind.errors.extend(self.errors)
bind.alias = self.alias
return self
# cast to targetType, "inheriting" stuff from self
bind = self.TargetType(parent=self)
return bind
def err(self, message):
self.errors.append(f'{type(self).__name__} "{self.key}" {message}')
self.errors.append(
f'{type(self).__name__.lower()} "{self.key}" {message}'
)
def warn(self, message):
self.warnings.append(
f'{type(self).__name__.lower()} "{self.key}" {message}'
)
class impulse(bind):
class Impulse(Bind):
def verify(self):
self.command = None
if not isinstance(self.fields, dict):
@ -118,15 +136,14 @@ class impulse(bind):
try:
self.command = self.fields.pop('command')
if isinstance(self.command, str):
self.command = self.command.split(';')
elif not isinstance(self.command, list):
self.err('`command` field must be argument of string or list')
self.command = None
except KeyError:
self.err('requires `command` field')
if isinstance(self.command, str):
self.command = self.command.split(';')
elif not isinstance(self.command, list):
self.err('`command` field must be argument of string or list')
self.command = None
def toTF2(self) -> str:
if self.alias:
@ -165,7 +182,8 @@ class impulse(bind):
elif cmd == 'build' or cmd == 'destroy':
restOfCmd = self.expandBuildings(restOfCmd)
elif cmd == 'load_itempreset' and restOfCmd.isalpha():
elif cmd == 'loadout' and restOfCmd.isalpha():
cmd = 'load_itempreset'
try:
restOfCmd = restOfCmd.lower()
restOfCmd = str(['a','b','c','d'].index(restOfCmd))
@ -173,6 +191,11 @@ class impulse(bind):
# not a load_itempreset shortcut
pass
elif cmd == 'unalias':
cmd = 'alias'
# adding empty arg to indicate unaliasing
restOfCmd += ' '
if restOfCmd != '':
cmd += ' ' + restOfCmd
instList[i] = cmd
@ -205,7 +228,7 @@ class impulse(bind):
return num
class hold(bind):
class Hold(Bind):
def verify(self):
self.press = None
self.release = None
@ -215,31 +238,32 @@ class hold(bind):
# verify press
try:
self.press = self.fields.pop('press')
if isinstance(self.press, str):
self.press = self.press.split(';')
elif not isinstance(self.press, list):
self.err('`press` field must be string or list')
self.press = None
except KeyError:
self.err('requires `press` field')
if isinstance(self.press, str):
self.press = self.press.split(';')
elif not isinstance(self.press, list):
self.err('`press` field must be string or list')
self.press = None
if self.press is None:
return
# verify release
try:
self.release = self.fields.pop('release')
except KeyError:
if isinstance(self.release, str):
self.release = self.release.split(';')
elif not isinstance(self.release, list):
self.err('`release` field must be string or list')
self.release = None
except popErrors:
self.warn('has no `release`, creating one')
# no release specified, do -action for each item in press
self.release = []
for cmd in self.press:
if cmd[0] == '+':
self.release.append('-' + cmd[1:])
if isinstance(self.release, str):
self.release = self.release.split(';')
elif not isinstance(self.release, list):
self.err('"release" field must be string or list')
self.release = None
def toTF2(self) -> str:
if self.alias:
bindOrAlias = 'alias'
@ -249,11 +273,11 @@ class hold(bind):
# Making impulse instances from self.press and .release
# allows them to share the shortcuts
pressObj = impulse(f'+{holdStr}', self.press)
pressObj = Impulse(f'+{holdStr}', self.press)
pressObj.alias = True
pressStr = pressObj.toTF2()
releaseObj = impulse(f'-{holdStr}', self.release)
releaseObj = Impulse(f'-{holdStr}', self.release)
releaseObj.alias = True
releaseStr = releaseObj.toTF2()
@ -262,10 +286,13 @@ class hold(bind):
# and never deactivating
self.key = '+' + self.key
return pressStr + releaseStr + f'{bindOrAlias} {self.key} "+{holdStr}"\n'
return (
pressStr + releaseStr
+ f'{bindOrAlias} {self.key} "+{holdStr}"\n'
)
class toggle(bind):
class Toggle(Bind):
def verify(self):
self.on = None
self.off = None
@ -275,31 +302,30 @@ class toggle(bind):
# verify on
try:
self.on = self.fields.pop('on')
if isinstance(self.on, str):
self.on = self.on.split(';')
elif not isinstance(self.on, list):
self.err('`on` field must be string or list')
self.on = None
except KeyError:
self.err('requires `on` field')
if isinstance(self.on, str):
self.on = self.on.split(';')
elif not isinstance(self.on, list):
self.err('`on` field must be string or list')
self.on = None
if self.on is None:
return
# verify off
try:
self.off = self.fields.pop('off')
except KeyError:
if isinstance(self.off, str):
self.off = self.off.split(';')
elif not isinstance(self.off, list):
self.err('`off` field must be string or list')
except popErrors:
# no off specified, do -action for each item in on
self.off = []
for cmd in self.on:
if cmd[0] == '+':
self.off.append('-' + cmd[1:])
if isinstance(self.off, str):
self.off = self.off.split(';')
elif not isinstance(self.off, list):
self.err('`off` field must be string or list')
self.off = None
def toTF2(self) -> str:
if self.alias:
bindOrAlias = 'alias'
@ -309,27 +335,28 @@ class toggle(bind):
onStr = f'{toggleStr}_on'
offStr = f'{toggleStr}_off'
onObj = impulse(onStr, self.on)
onObj = Impulse(onStr, self.on)
onObj.alias = True
toggleOn = onObj.toTF2()[
# remove trailing " and \n
:-2
]
toggleOn = onObj.toTF2()
# remove starting/trailing " and \n
toggleOn = toggleOn[:-2]
offObj = impulse(offStr, self.off)
offObj = Impulse(offStr, self.off)
offObj.alias = True
toggleOff = offObj.toTF2()[:-2]
return \
f'{toggleOn}; alias {toggleStr} {offStr}"\n' +\
f'{toggleOff}; alias {toggleStr} {onStr}"\n' +\
f'alias {toggleStr} "{onStr}"\n' +\
f'{bindOrAlias} {self.key} "{toggleStr}"\n'
return (
f'{toggleOn}; alias {toggleStr} {offStr}"\n'
+ f'{toggleOff}; alias {toggleStr} {onStr}"\n'
+ f'alias {toggleStr} "{onStr}"\n'
+ f'{bindOrAlias} {self.key} "{toggleStr}"\n'
)
class double(bind):
class Double(Bind):
defaultDict = {}
condDict = {}
bindNames = []
def verify(self):
self.primary = None
@ -345,114 +372,152 @@ class double(bind):
self.type = None
# either 'released' (default) or 'both'
self.cancel = 'released'
self.cancelBoth = False
# toggler
try:
self.condition = self.fields.pop('condition')
if self.condition not in validKeyList:
self.err(f'has invalid `condition` field: "{self.condition}"')
except KeyError:
except popErrors:
self.err('requires `condition` field')
if 'toggle' in self.fields:
try:
self.isToggle = self.fields.pop('toggle')
if not isinstance(self.isToggle, bool):
self.err(f'`toggle` field should be "yes" or "no", not "{self.isToggle}"')
self.err(
'`toggle` field should be "yes" or "no", '
+ f'not "{self.isToggle}"'
)
except popErrors:
self.isToggle = False
# type
try:
self.type = self.fields.pop('type')
if self.type not in [ type_.__name__ for type_ in self.bindTypes ]:
self.type = self.fields.pop('type').lower()
if self.type not in self.bindNames:
# catastrophic: invalid type
self.err(f'has invalid type: "{self.type}"')
return
except KeyError:
except popErrors:
# catastrophic: no type given
self.err('requires `type` field')
return
# cancel mode, must happend after type has been inferred
if 'cancel' in self.fields:
self.cancel = self.fields.pop('cancel')
if self.cancel in ('released', 'both'):
if self.cancel == 'both' and self.type != 'hold':
self.err(f'`cancel` field only affects "hold", not "{self.type}"')
elif isinstance(self.cancel, str):
self.err(f'`cancel` field must be "released" or "both", not "{self.cancel}"')
try:
cancel = self.fields.pop('cancel')
if not isinstance(cancel, str):
self.err(f'`cancel` field must be "released" or "both"')
else:
self.err(f'`cancel` field must be argument of "released" or "both"')
if cancel == 'both':
if self.type == 'hold':
self.cancelBoth = True
else:
self.err(
'`cancel` field only affects "hold", '
+ f'not "{self.type}"'
)
elif cancel != 'released':
self.err(
'`cancel` field must be "released" '
+ f'or "both", not "{cancel}"'
)
except popErrors:
cancel = 'released'
# primary action
try:
mainSection = self.fields.pop('primary')
mainBind = Bind(f'{self.type} {self.primStr}', mainSection)
mainBind = mainBind.toTargetType()
mainAction = bind(f'{self.type} {self.primStr}', mainSection)
self.primary = mainAction.toTargetType()
except KeyError:
self.errors.extend(mainBind.errors)
self.warnings.extend(mainBind.warnings)
self.errors.remove(f'invalid key name: "{self.primStr}"')
self.primary = mainBind
except popErrors:
self.err('requires `primary` field')
# secondary action
try:
altSection = self.fields.pop('secondary')
altBind = Bind(f'{self.type} {self.secondStr}', altSection)
altBind = altBind.toTargetType()
altBind = bind(f'{self.type} {self.secondStr}', altSection)
self.secondary = altBind.toTargetType()
except KeyError:
self.errors.extend(altBind.errors)
self.warnings.extend(altBind.warnings)
self.errors.remove(f'invalid key name: "{self.secondStr}"')
self.secondary = altBind
except popErrors:
self.err('requires `secondary` field')
def toTF2(self) -> str:
if self.alias:
bindOrAlias = 'alias'
else:
bindOrAlias = 'bind'
# Get code for primary and secondary actions
def toTF2(self) -> str:
# Get code for primary and secondary actions.
# alias=true so the toTF2() method aliases
# them instead of binding them
self.primary.alias = True
mainCode = self.primary.toTF2()
self.secondary.alias = True
altCode = self.secondary.toTF2()
# Make code to switch between the two actions
pShiftStr = f'+shift_{self.key}'
mShiftStr = f'-shift_{self.key}'
if self.cancel == 'both':
mainCode, altCode = self.cancelBoth(mainCode, altCode)
if self.cancelBoth:
mainCode, altCode = self.getCancelCode(mainCode, altCode)
if self.type == 'hold':
self.primStr = '+' + self.primStr
self.secondStr = '+' + self.secondStr
result = mainCode + altCode +\
f'alias {pShiftStr} "{bindOrAlias} {self.key} {self.secondStr}"\n' +\
f'alias {mShiftStr} "{bindOrAlias} {self.key} {self.primStr}"\n'+\
f'{bindOrAlias} {self.key} "{self.primStr}"\n'
shiftStr = f'shift_{self.key}'
shiftCode = self.getChangeCode(shiftStr)
self.addToCondDict(shiftStr)
try:
# If the condition key (like 'mouse4') already has toggles,
# just append another toggle string
changes = self.condDict[self.condition]['change_keys']
restores = self.condDict[self.condition]['restore_keys']
return mainCode + altCode + shiftCode
if pShiftStr not in changes:
# not already in changes
changes.append(pShiftStr)
restores.append(mShiftStr)
def getChangeCode(self, shift):
if self.alias:
bindOrAlias = 'alias'
else:
bindOrAlias = 'bind'
code = (
f'alias +{shift} "{bindOrAlias} {self.key} {self.secondStr}"\n'
+ f'alias -{shift} "{bindOrAlias} {self.key} {self.primStr}"\n'
)
except KeyError:
# If the condition key doesn't already exist, make it
if self.isToggle:
toggleObj = Toggle(shift, f'+{shift}')
toggleObj.alias = True # so it aliases instead of binding
code += toggleObj.toTF2()
else:
code += f'{bindOrAlias} {self.key} "{self.primStr}"\n'
return code
def addToCondDict(self, shiftStr):
if self.isToggle:
changeStr = shiftStr
else:
changeStr = '+' + shiftStr
restoreStr = '-' + shiftStr
if self.condition not in self.condDict:
# if not already present, make dict for key
self.condDict.update( {
self.condition: {
'change_keys': [ pShiftStr ],
'restore_keys': [ mShiftStr ],
'alias': self.alias
'change_keys': [],
'restore_keys': []
}
} )
return result
self.condDict[self.condition]['change_keys'].append(changeStr)
if self.isToggle == False:
self.condDict[self.condition]['restore_keys'].append(restoreStr)
def cancelBoth(self, mainCode, altCode) -> (str, str):
def getCancelCode(self, mainCode, altCode) -> (str, str):
# code to cancel both if either is released
# it copies the - statement from each to both.
# if it just extracted the name of the - statement,
@ -469,18 +534,13 @@ class double(bind):
altMinusStr = altMinusLine.split(' ', 2)[2][1:-1]
# remove duplicate - actions
mainMinusList = set(mainMinusStr.split(';'))
altMinusList = set(altMinusStr.split(';'))
uniqMain = mainMinusList.difference(altMinusList)
uniqAlt = altMinusList.difference(mainMinusList)
mainMinusSet = set(mainMinusStr.split(';'))
altMinusSet = set(altMinusStr.split(';'))
allCancels = mainMinusSet | altMinusSet
allCancelStr = ';'.join(allCancels)
mainMinusStr = ';'.join(uniqMain)
altMinusStr = ';'.join(uniqAlt)
if not uniqMain.issuperset(uniqAlt):
# main has things alt doesn't
mainLines[1] = mainLines[1][:-1] + f';{altMinusStr}"'
if not uniqAlt.issuperset(uniqMain):
altLines[1] = altLines[1][:-1] + f';{mainMinusStr}"'
altLines[1] = altLines[1][:-1] + f';{allCancelStr}"'
mainLines[1] = mainLines[1][:-1] + f';{allCancelStr}"'
return (
'\n'.join(mainLines) + '\n',
@ -488,7 +548,7 @@ class double(bind):
)
class repeat(bind):
class Repeat(Bind):
def verify(self):
self.interval = None
self.command = None
@ -497,25 +557,73 @@ class repeat(bind):
intervalStr = str(self.fields.pop('interval'))
self.interval = int(intervalStr)
if self.interval <= 0:
self.err('interval must be greater than 0')
except KeyError:
self.err('requires interval')
self.err('`interval` must be greater than 0')
except (KeyError, TypeError):
self.err('requires `interval` field')
except ValueError:
self.err(f'has invalid number of ticks: "{self.interval}"')
self.err(f'has invalid `interval`: "{self.interval}"')
except AttributeError:
self.err(f'requires `interval` field')
try:
self.command = self.fields.pop('command')
if not isinstance(self.command, (str, list)):
self.err('command must be string or list')
self.err('`command` must be string or list')
self.command = None
except KeyError:
self.err('requires command')
except popErrors:
self.err('requires `command` field')
def toTF2(self) -> str:
# commented-out placeholder
return f'// repeat {self.key}\n'
class Literal(Bind):
def verify(self):
self.text = ''
self.run = False
if not isinstance(self.fields, dict):
self.fields = {'text': self.fields}
if not self.alias:
try:
# keyname should be invalid, remove the error
self.errors.remove(
f'invalid key name: "{self.key}"'
)
except ValueError:
# if not invalid key, indicate as such
self.warn('should not use a key as a label')
if 'run' in self.fields:
self.run = self.fields.pop('run')
if not isinstance(self.run, bool):
self.errors.append(
f'`run` should be "yes" or "no", not "{self.run}"'
)
if not self.alias:
self.warn('`run` specified without alias')
try:
self.text = self.fields.pop('text')
except KeyError:
self.err('requires `text` field')
if isinstance(self.text, str):
self.text = self.text.split(';')
elif not isinstance(self.text, list):
self.err('argument must be of string or list')
def toTF2(self) -> str:
result = ';'.join(self.text)
if self.alias:
result = f'alias {self.key} "{result}"'
if self.run:
result += f'\n{self.key}'
return result + '\n'
# This is at the bottom because it has to happen after
# all inheritances have been completed
bind.bindTypes = bind.__subclasses__()
Bind.bindTypes = Bind.__subclasses__()
Double.bindNames = [ bind.__name__.lower() for bind in Bind.bindTypes ]

View File

@ -6,6 +6,7 @@ def verifyConfig(cfg: dict) -> (dict, dict):
verifiedConfig = {}
errors = {}
warnings = {}
# Do defaults first
defaults = []
@ -26,28 +27,27 @@ def verifyConfig(cfg: dict) -> (dict, dict):
for isclass, class_ in enumerate(classList):
classCFG = None
classBinds = []
className = class_
if isinstance(class_, str) and class_ in cfg:
classCFG = cfg.pop(class_)
elif isinstance(class_, tuple):
for tupClass in class_:
if tupClass in cfg:
classCFG = cfg.pop(tupClass)
className = class_[0]
break
if classCFG is None:
# Invalid class, this gets caught later.
# It may be less efficient this way, but
# it makes for more descriptive error messages
continue
classBinds = []
errMessages = []
warnMessages = []
for key, data in classCFG.items():
bind = tftypes.bind(key, data)
bind = tftypes.Bind(key, data)
bind = bind.toTargetType()
if isclass:
@ -56,9 +56,12 @@ def verifyConfig(cfg: dict) -> (dict, dict):
defaults.append(bind)
errMessages.extend(bind.errors)
warnMessages.extend(bind.warnings)
if len(errMessages) > 0:
errors.update( {className: errMessages} )
if len(warnMessages) > 0:
warnings.update( {className: warnMessages} )
verifiedConfig.update({className: classBinds})
@ -82,6 +85,8 @@ def verifyConfig(cfg: dict) -> (dict, dict):
if len(errors) > 0:
verifiedConfig.update({'errors': errors})
if len(warnings) > 0:
verifiedConfig.update({'warnings': warnings})
return verifiedConfig, defaults