Example #1
0
def ground_truth(args, truth_file):
    """
    There is but one truth. Conform.

    :param args: Namespace with the values of the CLI arguments
    :type args: ```Namespace```

    :param truth_file: contains the filename of the one true source
    :type truth_file: ```str```

    :return: Filenames and whether they were changed
    :rtype: ```OrderedDict```
    """
    arg2parse_emit_type = {
        "argparse_function":
        (parse.argparse_ast, emit.argparse_function, FunctionDef),
        "class": (parse.class_, emit.class_, ClassDef),
        "function": (parse.function, emit.function, FunctionDef),
    }

    parse_func, emit_func, type_wanted = arg2parse_emit_type[args.truth]
    search = _get_name_from_namespace(args, args.truth).split(".")

    with open(truth_file, "rt") as f:
        true_ast = ast_parse(f.read(), filename=truth_file)

    original_node = find_in_ast(search, true_ast)
    gold_ir = parse_func(
        original_node,
        **_default_options(node=original_node,
                           search=search,
                           type_wanted=type_wanted)())

    effect = OrderedDict()
    # filter(lambda arg: arg != args.truth, arg2parse_emit_type.keys()):
    for fun_name, (parse_func, emit_func,
                   type_wanted) in arg2parse_emit_type.items():
        search = list(
            strip_split(_get_name_from_namespace(args, fun_name), "."))

        filenames = getattr(args, pluralise(fun_name))
        assert isinstance(
            filenames,
            (list, tuple)), "Expected Union[list, tuple] got {!r}".format(
                type(filenames).__name__)

        effect.update(
            map(
                lambda filename: _conform_filename(
                    filename=filename,
                    search=search,
                    emit_func=emit_func,
                    replacement_node_ir=gold_ir,
                    type_wanted=type_wanted,
                ),
                filenames,
            ))

    return effect
Example #2
0
def _get_name_from_namespace(args, fun_name):
    """
    Gets the arg from the namespace which matches the given prefix

    :param args: Namespace with the values of the CLI arguments
    :type args: ```Namespace```

    :param fun_name: Name of the start of the function
    :type fun_name: ```str```

    :return: Argument from Namespace object
    :rtype: ```str```
    """
    return next(
        getattr(args, pluralise(arg))[0] for arg in vars(args).keys()
        if arg == "_".join((fun_name, "names")))
Example #3
0
def main(cli_argv=None, return_args=False):
    """
    Run the CLI parser

    :param cli_argv: CLI arguments. If None uses `sys.argv`.
    :type cli_argv: ```Optional[List[str]]```

    :param return_args: Primarily use is for tests. Returns the args rather than executing anything.
    :type return_args: ```bool```

    :returns: the args if `return_args`, else None
    :rtype: ```Optional[Namespace]```
    """
    _parser = _build_parser()
    args = _parser.parse_args(args=cli_argv)
    command = args.command
    args_dict = {k: v for k, v in vars(args).items() if k != "command"}
    if command == "sync":
        args = Namespace(
            **{
                k:
                v if k == "truth" or isinstance(v, list) or v is None else [v]
                for k, v in args_dict.items()
            })

        truth_file = getattr(args, pluralise(args.truth))
        if truth_file is None:
            _parser.error("--truth must be an existent file. Got: None")
        else:
            truth_file = truth_file[0]

        truth_file = path.realpath(path.expanduser(truth_file))

        number_of_files = sum(
            len(val) for key, val in vars(args).items()
            if isinstance(val, list) and not key.endswith("_names"))

        if number_of_files < 2:
            _parser.error(
                "Two or more of `--argparse-function`, `--class`, and `--function` must"
                " be specified")
        elif truth_file is None or not path.isfile(truth_file):
            _parser.error("--truth must be an existent file. Got: {!r}".format(
                truth_file))

        return args if return_args else ground_truth(args, truth_file)
    elif command == "sync_properties":
        for fname in "input_filename", "output_filename":
            if path.isfile(getattr(args, fname)):
                setattr(args, fname,
                        path.realpath(path.expanduser(getattr(args, fname))))
        if args.input_filename is None or not path.isfile(args.input_filename):
            _parser.error(
                "--input-file must be an existent file. Got: {!r}".format(
                    args.input_filename))
        elif args.output_filename is None or not path.isfile(
                args.output_filename):
            _parser.error(
                "--output-file must be an existent file. Got: {!r}".format(
                    args.output_filename))
        sync_properties(**args_dict)
    elif command == "gen":
        if path.isfile(args.output_filename):
            raise IOError(
                "File exists and this is a destructive operation. Delete/move {!r} then"
                " rerun.".format(args.output_filename))
        gen(**args_dict)
Example #4
0
 def test_pluralises(self) -> None:
     """ Tests that pluralises pluralises """
     self.assertEqual(pluralise(""), "")
     self.assertEqual(pluralise("goose"), "geese")
     self.assertEqual(pluralise("dolly"), "dollies")
     self.assertEqual(pluralise("genius"), "genii")
     self.assertEqual(pluralise("pass"), "passes")
     self.assertEqual(pluralise("zero"), "zeros")
     self.assertEqual(pluralise("casino"), "casinos")
     self.assertEqual(pluralise("hero"), "heroes")
     self.assertEqual(pluralise("church"), "churches")
     self.assertEqual(pluralise("x"), "xs")
     self.assertEqual(pluralise("ant"), "ants")
     self.assertEqual(pluralise("car"), "cars")
     self.assertEqual(pluralise("wish"), "wishes")
     self.assertEqual(pluralise("morphosis"), "morphosises")
     self.assertEqual(pluralise("s"), "ss")