Ejemplo n.º 1
0
 def test_loads_dumps(self):
   U = self.U['Pa*mm2']
   for s in '123456789Pa*mm2', '12.34Pa*mm2', '0Pa*mm2', '0.000012345Pa*mm2':
     v = stringly.loads(U, s)
     self.assertEqual(s, stringly.dumps(U, v))
   with self.assertRaises(ValueError):
     stringly.dumps(U, 'foo')
Ejemplo n.º 2
0
 def check(self, *args, **powers):
   s, v = args
   u = self.U(s)
   U = type(u)
   self.assertEqual(u, v)
   self.assertEqual(self.U._parse(s)[1], powers)
   self.assertEqual(stringly.dumps(U, u), s)
   self.assertEqual(stringly.loads(U, s), u)
Ejemplo n.º 3
0
def run(func, *, args=None, loaduserconfig=True):
    '''parse command line arguments and call function'''

    if args is None:
        args = sys.argv.copy()

    scriptname = os.path.basename(args.pop(0))
    sig = inspect.signature(func)
    doc = stringly.util.DocString(func)

    argdocs = doc.argdocs
    for param in sig.parameters.values():
        if isinstance(param.annotation, str):
            argdocs[param.name] = param.annotation

    types = {
        param.name: param.annotation
        for param in inspect.signature(setup).parameters.values()
        if param.default is not param.empty
    }
    for param in sig.parameters.values():
        if param.annotation is not param.empty and not isinstance(
                param.annotation, str):
            types[param.name] = param.annotation
        elif param.default is not param.empty:
            types[param.name] = type(param.default)
        else:
            sys.exit('cannot infer type of argument {!r}'.format(param.name))

    if '-h' in args or '--help' in args:
        usage = []
        if doc.text:
            usage.append(doc.text)
            usage.append('\n\n')
        usage.append('USAGE: {}'.format(scriptname))
        if doc.presets:
            usage.append(' [{}]'.format('|'.join(doc.presets)))
        if sig.parameters:
            usage.append(' [arg=value] [...]\n')
            defaults = doc.defaults
            for param in sig.parameters.values():
                usage.append('\n  {}'.format(param.name))
                if param.name in defaults:
                    usage.append(' [{}]'.format(defaults[param.name]))
                elif param.default is not param.empty:
                    usage.append(' [{}]'.format(
                        stringly.dumps(types[param.name], param.default)))
                if param.name in argdocs:
                    usage.extend(
                        textwrap.wrap(argdocs[param.name],
                                      initial_indent='\n    ',
                                      subsequent_indent='\n    '))
        print(''.join(usage))
        sys.exit(1)

    strargs = doc.defaults
    if args and args[0] in doc.presets:
        strargs.update(doc.presets[args.pop(0)])
    for arg in args:
        name, sep, value = arg.lstrip('-').partition('=')
        if not sep:
            if name in types:
                value = 'yes'
            elif name.startswith('no') and name[2:] in types:
                name = name[2:]
                value = 'no'
            else:
                print('argument {!r} requires a value'.format(name))
                sys.exit(2)
        strargs[name] = value

    funcargs = {}
    setupargs = {}

    if loaduserconfig:
        home = os.path.expanduser('~')
        for path in os.path.join(home, '.config', 'nutils',
                                 'config'), os.path.join(home, '.nutilsrc'):
            if os.path.isfile(path):
                setupargs.update(_load_rcfile(path))

    for name, s in strargs.items():
        if name not in types:
            sys.exit('unexpected argument: {}'.format(name))
        try:
            value = stringly.loads(types[name], s)
        except stringly.error.StringlyError as e:
            print(e)
            sys.exit(2)
        (funcargs if name in sig.parameters else setupargs)[name] = value

    kwargs = [(param.name,
               stringly.dumps(types[param.name],
                              funcargs.get(param.name, param.default)),
               argdocs.get(param.name)) for param in sig.parameters.values()]

    with setup(scriptname=scriptname, kwargs=kwargs, **setupargs):
        func(**funcargs)