def transform_chunk( code: str, quote_type: str = QuoteTypes.triple_double) -> Tuple[str, bool]: """Convert a block of code to an f-string Args: code: The code to convert. quote_type: the quote type to use for the transformed result Returns: Tuple: resulting code, boolean: was it changed? """ try: tree = ast.parse(code) converted, changed, str_in_str = fstringify_node(copy.deepcopy(tree)) except (SyntaxError, FlyntException, Exception): return code, False else: if changed: new_code = astor.to_source(converted) new_code = new_code.strip() new_code = set_quote_type( new_code, quote_type if not str_in_str else QuoteTypes.double) new_code = new_code.replace("\n", "\\n") new_code = new_code.replace("\t", "\\t") try: ast.parse(new_code) except Exception: return code, False else: return new_code, changed return code, False
def transform_concat(code: str, *args, **kwargs) -> Tuple[str, bool]: tree = ast.parse(code) ft = FstringifyTransformer() ft.visit(tree) new_code = astor.to_source(tree) if new_code[-1] == "\n": new_code = new_code[:-1] new_code = set_quote_type(new_code, QuoteTypes.double) return new_code, ft.counter > 0
def transform_chunk( code: str, quote_type: str = QuoteTypes.triple_double) -> Tuple[str, bool]: """Convert a block of code to an f-string Args: code: The code to convert. quote_type: the quote type to use for the transformed result Returns: Tuple: resulting code, boolean: was it changed? """ try: tree = ast.parse(code) converted, changed, str_in_str = fstringify_node(copy.deepcopy(tree)) except (SyntaxError, FlyntException, Exception) as e: if state.verbose: if isinstance(e, ConversionRefused): print(f"Not converting code '{code}': {e}") print(e) else: print(f"Exception {e} during conversion of code '{code}'") traceback.print_exc() state.invalid_conversions += 1 return code, False else: if changed: new_code = astor.to_source(converted) new_code = new_code.strip() new_code = set_quote_type( new_code, quote_type if not str_in_str else QuoteTypes.double) new_code = new_code.replace("\n", "\\n") new_code = new_code.replace("\t", "\\t") try: ast.parse(new_code) except Exception as e: if state.verbose: print( f"Failed to parse transformed code '{new_code}' given original '{code}'" ) print(e) traceback.print_exc() state.invalid_conversions += 1 return code, False else: return new_code, changed return code, False
def transform_chunk( code: str, quote_type: str = QuoteTypes.triple_double) -> Tuple[str, Dict]: """Convert a block of with a %-formatted string to an f-string Args: code (str): The code to convert. Returns: The code formatted with f-strings if possible else it's left unchanged. """ converted = None meta = dict(changed=False, lineno=1, col_offset=-22, skip=True) try: tree = ast.parse(code) # from flynt.transform.util import pp_ast # pp_ast(tree) converted, meta = fstringify_node(copy.deepcopy(tree)) except SyntaxError as e: meta["skip"] = code.rstrip().endswith( ":") or "cannot include a blackslash" in str(e) except FlyntException: meta["skip"] = False except Exception as e2: meta["skip"] = False if meta["changed"] and converted: new_code = astor.to_source(converted) new_code = new_code.strip() new_code = set_quote_type(new_code, quote_type) new_code = new_code.replace("\n", "\\n") new_code = new_code.replace("\t", "\\t") new_code = new_code.replace("{{{{", "{{") new_code = new_code.replace("}}}}", "}}") try: ast.parse(new_code) except Exception: meta["changed"] = False return code, meta else: return new_code, meta return code, meta
def transform_concat(code: str, *args, **kwargs) -> Tuple[str, bool]: tree = ast.parse(f"({code})") ft = ConcatTransformer() ft.visit(tree) il = FstrInliner() il.visit(tree) new_code = astor.to_source(tree) if new_code[-1] == "\n": new_code = new_code[:-1] new_code = new_code.replace("\n", "\\n") if new_code[:4] == 'f"""': new_code = set_quote_type(new_code, QuoteTypes.double) return new_code, ft.counter > 0
def test_single_from_triple(): code = '"""alpha123"""' expected = "'alpha123'" assert set_quote_type(code, QuoteTypes.single) == expected
def test_initial_doesnt_matter(quote_type): code = random.choice(["'abra'", '"bobro"', "'''abra'''", '"""bobro"""']) assert get_quote_type(set_quote_type(code, quote_type)) == quote_type
def test_cycle(code): assert set_quote_type(code, get_quote_type(code)) == code