예제 #1
0
파일: syntax.py 프로젝트: mbhall88/snakefmt
 def to_key_val_mode(self, token: Token):
     if not self.has_value():
         raise InvalidParameterSyntax(
             f"L{token.start[0]}:Operator = used with no preceding key")
     try:
         exec(f"{self.value} = 0")
     except SyntaxError:
         raise InvalidParameterSyntax(
             f"L{token.start[0]}:Invalid key {self.value}") from None
     self.key = self.value
     self.value = ""
예제 #2
0
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        if len(self.keyword_params) > 0:
            raise InvalidParameterSyntax((
                f"{self.line_nb}{self.keyword_name} definition does not accept "
                f"key/value parameters"))
예제 #3
0
    def format_param(
        self,
        parameter: Parameter,
        target_indent: int,
        inline_formatting: bool,
        param_list: bool = True,
    ) -> str:
        string_indent = TAB * target_indent
        if inline_formatting:
            target_indent = 0
        val = str(parameter)

        try:
            # A snakemake parameter is syntactically like a function parameter
            ast_parse(f"param({val})")
        except SyntaxError:
            raise InvalidParameterSyntax(f"{parameter.line_nb}{val}") from None

        if inline_formatting or param_list:
            val = " ".join(
                val.rstrip().split("\n")
            )  # collapse strings on multiple lines
        extra_spacing = 0
        if param_list:
            val = f"f({val})"
            extra_spacing = 3
        val = self.run_black_format_str(val, target_indent, extra_spacing)
        if param_list:
            match_equal = re.match(r"f\((.*)\)", val, re.DOTALL)
            val = match_equal.group(1)
            val = textwrap.dedent(val)

        val = self.align_strings(val, target_indent)

        result = ""
        if not inline_formatting:
            for comment in parameter.pre_comments:
                result += f"{string_indent}{comment}\n"
        result += val.strip("\n")
        if param_list:
            result += ","
        post_comment_iter = iter(parameter.post_comments)
        if parameter._has_inline_comment:
            result += f"{COMMENT_SPACING}{next(post_comment_iter)}"
        result += "\n"
        for comment in post_comment_iter:
            result += f"{string_indent}{comment}\n"
        return result
예제 #4
0
 def process_token(self, cur_param: Parameter) -> Parameter:
     token_type = self.token.type
     if token_type == tokenize.INDENT:
         self.cur_indent += 1
     elif token_type == tokenize.DEDENT:
         if self.cur_indent > 0:
             self.cur_indent -= 1
     elif token_type == tokenize.NEWLINE or token_type == tokenize.NL:
         self.found_newline = True
         if cur_param.has_value():
             cur_param.add_elem(self.token)
     elif token_type == tokenize.COMMENT and not self.in_brackets:
         if str(cur_param) == "" and self.latest_pushed_param is not None:
             target = self.latest_pushed_param.comments
         else:
             target = cur_param.comments
         target.append(" " + self.token.string)
     elif is_equal_sign(self.token) and not self.in_brackets:
         cur_param.to_key_val_mode(self.token)
     elif is_comma_sign(
             self.token) and not self.in_brackets and not self.in_lambda:
         self.flush_param(cur_param)
         cur_param = Parameter(self.line_nb)
     elif token_type != tokenize.ENDMARKER:
         if brack_open(self.token):
             self._brackets.append(self.token.string)
         if brack_close(self.token):
             self._brackets.pop()
         if is_colon(self.token) and self.in_lambda:
             self.in_lambda = False
         if len(cur_param.value.split()) == 1:
             if cur_param.value == "lambda":
                 self.in_lambda = True
             if self.incident_vocab.recognises(cur_param.value):
                 raise InvalidParameterSyntax((
                     f"{self.line_nb}Over-indented recognised keyword found: "
                     f"'{cur_param.value}'"))
         cur_param.add_elem(self.token)
     return cur_param
예제 #5
0
    def format_param(
        self,
        parameter: Parameter,
        target_indent: int,
        inline_formatting: bool,
        single_param: bool = False,
    ) -> str:
        if inline_formatting:
            target_indent = 0
        comments = f"\n{TAB * target_indent}".join(parameter.comments)
        val = str(parameter)

        try:
            # A snakemake parameter is syntactically like a function parameter
            ast_parse(f"param({val})")
        except SyntaxError:
            raise InvalidParameterSyntax(f"{parameter.line_nb}{val}") from None

        if inline_formatting:
            val = val.replace("\n", "")  # collapse strings on multiple lines
        try:
            val = self.run_black_format_str(val, target_indent)
        except InvalidPython:
            if "**" in val:
                val = val.replace("** ", "**")

        val = self.align_strings(val, target_indent)
        if parameter.has_a_key():  # Remove space either side of '='
            match_equal = re.match("(.*?) = (.*)", val, re.DOTALL)
            val = f"{match_equal.group(1)}={match_equal.group(2)}"

        val = val.strip("\n")
        if single_param:
            result = f"{val}{comments}\n"
        else:
            result = f"{val},{comments}\n"
        return result