Add check command, remove _ast import
- The check command checks to see if there is anything missing from the specified output file. - All types in the `_ast' module are also exported from the `ast' module, so there is no need to use `_ast' explicitly. - Don't raise an exception when a value from the specification doesn't match a predicate, the `check' command will take care of this. - Place some functions outside of their previous classes. These are used by several classes/methods and they need no state from these classes.
This commit is contained in:
parent
ea8763fd0d
commit
0988389972
1 changed files with 46 additions and 28 deletions
|
@ -1,6 +1,5 @@
|
|||
from __future__ import print_function
|
||||
|
||||
import _ast
|
||||
import ast
|
||||
import os
|
||||
import os.path
|
||||
|
@ -21,12 +20,34 @@ def write_settings(specs, out, values=None):
|
|||
.format(file=specs.OUTPUT_FILE), file=out)
|
||||
|
||||
for key, spec in specs.SETTINGS:
|
||||
value = values.get(key, spec['initial'])
|
||||
|
||||
if (spec['predicate'](value)):
|
||||
value = values.get(key, spec[1])
|
||||
print(key, repr(value), sep=' = ', file=out)
|
||||
|
||||
|
||||
def get_node_value(node):
|
||||
if isinstance(node, ast.Name):
|
||||
return ast.literal_eval(node.id)
|
||||
elif isinstance(node, ast.Str):
|
||||
return node.s
|
||||
elif isinstance(node, ast.Num):
|
||||
return node.n
|
||||
else:
|
||||
raise RuntimeError('Invalid type for %s: %s' % (key, repr(value)))
|
||||
return node
|
||||
|
||||
|
||||
def get_settings_from(filename):
|
||||
res = {}
|
||||
|
||||
with open(filename, 'r') as f:
|
||||
tree = ast.parse('\n'.join(f.readlines()), filename)
|
||||
for node in ast.iter_child_nodes(tree):
|
||||
if isinstance(node, ast.Assign):
|
||||
for target in node.targets:
|
||||
res[target.id] = get_node_value(node.value)
|
||||
else:
|
||||
print(node, node._fields)
|
||||
|
||||
return res
|
||||
|
||||
|
||||
class PreviewMixin(object):
|
||||
|
@ -62,35 +83,29 @@ class Generate(pycommand.CommandBase, PreviewMixin):
|
|||
class Update(pycommand.CommandBase, PreviewMixin):
|
||||
usagestr = 'usage: topple update [--preview|-p]'
|
||||
|
||||
def _get_value(self, node):
|
||||
if isinstance(node, _ast.Name):
|
||||
return eval(node.id)
|
||||
elif isinstance(node, _ast.Str):
|
||||
return node.s
|
||||
elif isinstance(node, _ast.Num):
|
||||
return node.n
|
||||
else:
|
||||
return node
|
||||
def run(self):
|
||||
sys.path.insert(0, os.getcwd())
|
||||
filename = 'settings_local.py'
|
||||
res = get_settings_from(filename)
|
||||
specs = get_setting_specs(self.parentFlags['module'] or 'toppler')
|
||||
self.write(specs.OUTPUT_FILE, specs, res)
|
||||
|
||||
def _get_values(self, filename):
|
||||
res = {}
|
||||
|
||||
with open(filename, 'r') as f:
|
||||
tree = ast.parse('\n'.join(f.readlines()), filename)
|
||||
for node in ast.iter_child_nodes(tree):
|
||||
if isinstance(node, _ast.Assign):
|
||||
res[node.targets[0].id] = self._get_value(node.value)
|
||||
else:
|
||||
print(node, node._fields)
|
||||
|
||||
return res
|
||||
class Check(pycommand.CommandBase):
|
||||
usagestr = 'usage: topple check'
|
||||
|
||||
def run(self):
|
||||
sys.path.insert(0, os.getcwd())
|
||||
filename = 'settings_local.py'
|
||||
res = self._get_values(filename)
|
||||
res = get_settings_from(filename)
|
||||
specs = get_setting_specs(self.parentFlags['module'] or 'toppler')
|
||||
self.write(specs.OUTPUT_FILE, specs, res)
|
||||
|
||||
for key, spec in specs.SETTINGS:
|
||||
if key not in res:
|
||||
print('Missing setting:', key)
|
||||
elif not spec[0](res[key]):
|
||||
print('Value "%s" for %s does not pass predicate `%s\''
|
||||
% (res[key], key, spec[0].func_name))
|
||||
|
||||
|
||||
class Topple(pycommand.CommandBase):
|
||||
|
@ -99,6 +114,7 @@ class Topple(pycommand.CommandBase):
|
|||
'Commands:\n'
|
||||
' generate Generate a new settings file.\n'
|
||||
' update Update an existing settings file.\n'
|
||||
' check Check the validity of an existing settings file.'
|
||||
)
|
||||
optionList = (('module', ('m', '<modulename>',
|
||||
'Use specified python module.')),)
|
||||
|
@ -117,6 +133,8 @@ class Topple(pycommand.CommandBase):
|
|||
cmd = Generate(argv=self.args[1:])
|
||||
elif self.args[0] == 'update':
|
||||
cmd = Update(argv=self.args[1:])
|
||||
elif self.args[0] == 'check':
|
||||
cmd = Check(argv=self.args[1:])
|
||||
else:
|
||||
print('Undefined command: {cmd}'.format(cmd=self.args[0]))
|
||||
return 1
|
||||
|
|
Loading…
Reference in a new issue