Exemple #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')
Exemple #2
0
def create_log(app, env, node, contnode):
    logger = sphinx.util.logging.getLogger(__name__)

    if node['reftype'] == 'nutils-log':
        script = node.get('script')
        scriptname = str(script.relative_to(project_root))

        cmdline_args = node['reftarget']
        cmdline = ' '.join(map(shlex.quote, [scriptname, *cmdline_args]))

        target = '_logs/{}/index'.format(
            urllib.parse.quote(cmdline, safe='').replace('%', '+'))

        dst_log = (pathlib.Path(app.builder.outdir) / target).parent
        if dst_log.exists(
        ) and dst_log.stat().st_mtime > script.stat().st_mtime:
            logger.debug(
                'Skip building log of {cmdline} because it already exists and '
                'is newer than {script}.  Please touch {script} to force a rebuild.'
                .format(script=scriptname, cmdline=cmdline))
        else:
            if dst_log.exists():
                logger.debug('purging old log files... {}'.format(dst_log))
                shutil.rmtree(str(dst_log))
            else:
                dst_log.parent.mkdir(parents=True, exist_ok=True)
            logger.info('creating log... {}'.format(cmdline))
            script_dict = runpy.run_path(str(script),
                                         run_name='__log_builder__')
            # Parse cmdline.
            func = script_dict['main']
            params = inspect.signature(func).parameters
            doc = stringly.util.DocString(func)
            kwargs = doc.defaults.copy()
            kwargs.update(arg.split('=', 1) for arg in cmdline_args if arg)
            # Run script.
            import matplotlib.testing
            matplotlib.testing.setup()
            with nutils.cli._htmllog(
                    outdir=str(dst_log),
                    scriptname=scriptname,
                    kwargs=[(name, kwargs[name], doc.argdocs[name])
                            for name in params
                            ]) as log, treelog.set(log), nutils.matrix.backend(
                                'scipy'), nutils.warnings.via(treelog.warning):
                func(
                    **{
                        name: stringly.loads(params[name].annotation,
                                             kwargs[name])
                        for name in params
                    })
            (dst_log / 'log.html').rename(dst_log / 'index.html')

        refnode = docutils.nodes.reference('',
                                           '',
                                           internal=False,
                                           refuri=app.builder.get_relative_uri(
                                               env.docname, target))
        refnode.append(contnode)
        return refnode
Exemple #3
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)
Exemple #4
0
 def test_bind(self):
   T = self.U['m']
   self.assertEqual(T.__name__, 'unit:m')
   stringly.loads(T, '2in')
   with self.assertRaises(ValueError):
     stringly.loads(T, '2kg')
Exemple #5
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)