def try_on_file_string_concat(filename: str, multiline): """ Given a file name (something.py) find this file in test/integration/samples_in, run flint_str on its content, write result to test/integration/actual_out/something.py, and compare the result with test/integration/expected_out/something.py""" txt_in = read_in(filename) out, edits = fstringify_concats(txt_in, multiline=multiline, len_limit=None) write_output_file(filename, out) return out, read_expected(filename)
def test_concat_two_sides(): s_in = """t = 'T is a string of value: ' + val + ' and thats great!'""" s_expected = """t = f"T is a string of value: {val} and thats great!\"""" s_out, count = process.fstringify_concats(s_in) assert s_out == s_expected
def test_concat(): s_in = """msg = a + " World\"""" s_expected = """msg = f"{a} World\"""" s_out, count = process.fstringify_concats(s_in) assert s_out == s_expected
def _fstringify_file( filename, multiline, len_limit, transform_concat=False ) -> Tuple[bool, int, int, int]: """ :return: tuple: (changes_made, n_changes, length of original code, length of new code) """ with open(filename, encoding="utf-8") as f: contents = f.read() def default_result(): return False, 0, len(contents), len(contents) try: ast_before = ast.parse(contents) except SyntaxError: if not state.quiet: print(f"Can't parse {filename} as a python file.") return default_result() try: new_code, changes = fstringify_code_by_line( contents, multiline=multiline, len_limit=len_limit ) if transform_concat: new_code, concat_changes = fstringify_concats( new_code, multiline=multiline, len_limit=len_limit ) changes += concat_changes state.concat_changes += concat_changes except Exception as e: if not state.quiet: print(f"Skipping fstrings transform of file {filename} due to {e}") if state.verbose: traceback.print_exc() return default_result() if new_code == contents: return default_result() try: ast_after = ast.parse(new_code) except SyntaxError: print(f"Faulty result during conversion on {filename} - skipping.") if state.verbose: print(new_code) traceback.print_exc() return default_result() if not len(ast_before.body) == len(ast_after.body): print( f"Faulty result during conversion on {filename}: " f"statement count has changed, which is not intended - skipping." ) return default_result() with open(filename, "w", encoding="utf-8") as f: f.write(new_code) return True, changes, len(contents), len(new_code)
def fstringify_file(filename, multiline, len_limit, pyup=False, transform_concat=False) -> Tuple[bool, int, int, int]: """ :return: tuple: (changes_made, n_changes, length of original code, length of new code) """ with open(filename, encoding="utf-8") as f: contents = f.read() def default_result(): return False, 0, len(contents), len(contents) try: ast_before = ast.parse(contents) except SyntaxError: print(f"Can't parse {filename} as a python file.") return default_result() try: new_code, changes = fstringify_code_by_line(contents, multiline=multiline, len_limit=len_limit) if transform_concat: new_code, concat_changes = fstringify_concats(new_code, multiline=multiline, len_limit=len_limit) changes += concat_changes except Exception as e: print(f"Skipping fstrings transform of file {filename} due to {e}") traceback.print_exc() result = default_result() else: if new_code == contents: result = default_result() else: try: ast_after = ast.parse(new_code) except SyntaxError: print( f"Faulty result during conversion on {filename} - skipping." ) return default_result() if not len(ast_before.body) == len(ast_after.body): print( f"Faulty result during conversion on {filename} - skipping." ) return default_result() with open(filename, "w", encoding="utf-8") as f: f.write(new_code) result = True, changes, len(contents), len(new_code) if not pyup: return result else: class Args: def __init__(self, **kwargs): self.__dict__.update(kwargs) args = Args( min_version=(3, 6), keep_percent_format=False, exit_zero_even_if_changed=False, ) with spy_on_file_io(): changed = pyupgrade._fix_file(filename, args) if changed: len_before, len_after = charcount_stats(filename) return True, result[1], result[2], len_after else: return result
def _fstringify_file( filename, multiline, len_limit, transform_concat=False ) -> Tuple[bool, int, int, int]: """ :return: tuple: (changes_made, n_changes, length of original code, length of new code) """ def default_result(): return False, 0, len(contents), len(contents) with open(filename, encoding="utf-8", newline="") as f: try: contents = f.read() except UnicodeDecodeError as e: contents = '' print(f'Exception while reading {filename}: {e}') return default_result() try: ast_before = ast.parse(contents) except SyntaxError: if not state.quiet: print(f"Can't parse {filename} as a python file.") return default_result() try: new_code, changes = fstringify_code_by_line( contents, multiline=multiline, len_limit=len_limit ) if transform_concat: new_code, concat_changes = fstringify_concats( new_code, multiline=multiline, len_limit=len_limit ) changes += concat_changes state.concat_changes += concat_changes except Exception as e: if not state.quiet: if str(e): msg = str(e) else: msg = e.__class__.__name__ print(f"Skipping fstrings transform of file {filename} due to {msg}.") if state.verbose: traceback.print_exc() return default_result() if new_code == contents: return default_result() try: ast_after = ast.parse(new_code) except SyntaxError: print(f"Faulty result during conversion on {filename} - skipping.") if state.verbose: print(new_code) traceback.print_exc() return default_result() if not len(ast_before.body) == len(ast_after.body): print( f"Faulty result during conversion on {filename}: " f"statement count has changed, which is not intended - skipping." ) return default_result() if state.dry_run: for l in unified_diff( contents.split("\n"), new_code.split("\n"), fromfile=filename ): print(l) else: with open(filename, "w", encoding="utf-8", newline="") as f: f.write(new_code) return True, changes, len(contents), len(new_code)