Source code for sisl.utils.sdata

#!/usr/bin/env python
"""
Easy conversion of data from different formats to other formats.
"""
from __future__ import print_function, division

import sys
import os
import os.path as osp
import argparse

__all__ = ['sdata']


def argparse_patch(parser):
    """ Patch the argparse module such that one may process the Namespace in subparsers

    This patch have been created by: 
      paul.j3 (http://bugs.python.org/file44363/issue27859test.py)
    and adapted by Nick R. Papior with minor edits.

    Parameters
    ----------
    parser: ArgumentParser
       parser to be patched
    """
    class MySubParsersAction(argparse._SubParsersAction):

        def __call__(self, parser, namespace, values, option_string=None):
            parser_name = values[0]
            arg_strings = values[1:]

            # set the parser name if requested
            if self.dest is not argparse.SUPPRESS:
                setattr(namespace, self.dest, parser_name)

            # select the parser
            try:
                parser = self._name_parser_map[parser_name]
            except KeyError:
                args = {'parser_name': parser_name,
                        'choices': ', '.join(self._name_parser_map)}
                msg = _('unknown parser %(parser_name)r (choices: %(choices)s)') % args
                raise ArgumentError(self, msg)

            # parse all the remaining options into the namespace
            # store any unrecognized options on the object, so that the top
            # level parser can decide what to do with them

            # pass parent namespace (it is now the users responsibility to
            # not have dublicate .default parameters)
            namespace, arg_strings = parser.parse_known_args(arg_strings, namespace)

            ## ORIGINAL
            #subnamespace, arg_strings = parser.parse_known_args(arg_strings, None)
            #for key, value in vars(subnamespace).items():
            #    setattr(namespace, key, value)

            if arg_strings:
                vars(namespace).setdefault(_UNRECOGNIZED_ARGS_ATTR, [])
                getattr(namespace, _UNRECOGNIZED_ARGS_ATTR).extend(arg_strings)
    parser.register('action', 'parsers', MySubParsersAction)


[docs]def sdata(argv=None, sile=None): from . import cmd # The file *MUST* be the first argument # (except --help|-h) # We cannot create a separate ArgumentParser to retrieve a positional arguments # as that will grab the first argument for an option! # Start creating the command-line utilities that are the actual ones. description = """ This manipulation utility can handle nearly all files in the sisl code in changing ways. It handles files dependent on type AND content. """.format(osp.basename(sys.argv[0])) if argv is not None: # We keep the arguments pass elif len(sys.argv) == 1: # no arguments # fake a help argv = ['--help'] else: argv = sys.argv[1:] # Ensure that the arguments have pre-pended spaces argv = cmd.argv_negative_fix(argv) p = argparse.ArgumentParser("Manipulates sisl Sile's for manipulation.", formatter_class=argparse.RawDescriptionHelpFormatter, description=description, conflict_handler='resolve') # Patch the parser to allow namespace passing in subparsers... argparse_patch(p) # Now try and figure out the actual arguments p, ns, argv = cmd.collect_arguments(argv, input=True, argumentparser=p) # Now the arguments should have been populated # and we will sort out if the input options # is only a help option. if not hasattr(ns, '_input_file'): # Then there are no input files... # It is difficult to create an adaptable script # with no adaptee... ;) if not (('--help' in argv) or ('-h' in argv)): # Re-create the argument parser with the help description argv = ['--help'] description += """ One *must* supply a file before a help menu can be generated. The help menu depends on the type of Sile that is specified. """ p = argparse.ArgumentParser("Manipulates sisl Sile's for manipulation.", formatter_class=argparse.RawDescriptionHelpFormatter, description=description) # We are good to go!!! p.parse_args(argv, namespace=ns) return 0